将32位寄存器压入'16位堆栈'

时间:2012-09-07 09:59:49

标签: assembly nasm

这有点像三个问题,无论如何它在这里:

1-所以我一直在这里寻找我的问题的答案,有人从某个地方引用了这个:

  

堆栈段的address-size属性确定堆栈   指针大小(16,32或64位)。的操作数大小属性   当前代码段确定堆栈指针的数量   递减(2个,4个或8个字节)。

有人可以通过像我这样的汇编新手能够理解的方式向我解释这个吗?

2-问题是我创建了这个小堆栈:

setStack:                  ; setup a small stack at 0x9B000

  cli                      ; disable interrupts
  mov AX, 0x9000
  mov SS, AX
  mov SP, 0xB000
  sti                      ; re-enable interrupts

由于我(最确定的缺乏)对1的引用的理解,我假设这个堆栈有一个16位指针,并且当它们被调用时,push / pop指令递减/递增2个字节?我假设正确吗?

3-假设我已经假设正确(即:即使我没有,请回答下一个问题,就像我做的那样)下一个语句会在堆栈上执行什么?

push ECX                   ; ECX is a 32 bit register

先感谢Stack Overflow的亲切居民。

2 个答案:

答案 0 :(得分:1)

如果堆栈段设置为16位堆栈,则push / pop将引用SP,堆栈应在两字节边界上对齐。按下一个16位寄存器将占用一个插槽,按下一个32位寄存器将占用两个插槽。您可以使用以下代码对自己进行验证:

push eax
pop ax
pop bx

如果堆栈段设置为32位堆栈,则push / pop将引用ESP,堆栈应在四字节边界上对齐。按下32位寄存器将占用一个插槽。按下16位寄存器将导致堆栈未对齐。这是一件坏事。

以下网址是英特尔手册中推送说明规范的副本。我已将状态机附加到推送指令。

http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/vc266.htm

IF StackAddrSize  32
THEN

IF OperandSize  32
THEN
ESP  ESP - 4;
SS:ESP  SRC; (* push doubleword *)
ELSE (* OperandSize  16*)
ESP  ESP - 2;
SS:ESP  SRC; (* push word *)
FI;

ELSE (* StackAddrSize  16*)

IF OperandSize  16
THEN
SP  SP - 2;
SS:SP  SRC; (* push word *)
ELSE (* OperandSize  32*)
SP  SP - 4;
SS:SP  SRC; (* push doubleword *)
FI;

FI;

答案 1 :(得分:0)

试试吧! (看起来你在“你自己的操作系统”,但可能有dos?)

; nasm -f bin -o test32.com test32.asm
bits 16
org 100h

mov eax, 11112222h
push eax
pop ax
pop dx
call ax2hex
mov ax, dx
call ax2hex
ret

;-------------------
ax2hex:
    push cx
    push dx

    mov cx, 4           ; four digits to show

.top
    rol ax, 4           ; rotate one digit into position
    mov dl, al          ; make a copy to process
    and dl, 0Fh         ; mask off a single (hex) digit
    cmp dl, 9           ; is it in the 'A' to 'F' range?
    jbe .dec_dig        ; no, skip it
    add dl, 7           ; adjust
.dec_dig:
    add dl, 30h         ; convert to character

    push ax
    mov ah, 2           ; print the character
    int 21h
    pop ax

    loop .top

    pop dx
    pop cx
    ret
;--------------------------

; nasm -f bin -o test32.com test32.asm bits 16 org 100h mov eax, 11112222h push eax pop ax pop dx call ax2hex mov ax, dx call ax2hex ret ;------------------- ax2hex: push cx push dx mov cx, 4 ; four digits to show .top rol ax, 4 ; rotate one digit into position mov dl, al ; make a copy to process and dl, 0Fh ; mask off a single (hex) digit cmp dl, 9 ; is it in the 'A' to 'F' range? jbe .dec_dig ; no, skip it add dl, 7 ; adjust .dec_dig: add dl, 30h ; convert to character push ax mov ah, 2 ; print the character int 21h pop ax loop .top pop dx pop cx ret ;--------------------------

唯一重要的意见是CPU的意见!

最佳, 弗兰克