这有点像三个问题,无论如何它在这里:
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的亲切居民。
答案 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的意见!
最佳, 弗兰克