将寄存器与堆栈顶部的项目进行比较?

时间:2013-06-25 03:44:24

标签: assembly x86-16

是否可以将寄存器与堆栈顶部的项目进行比较,而不先将其弹出?

通过这种方式,我可以做到,但我必须首先弹出值:

push 1
pop ax
cmp ax,1
jz equal

是否可以在不修改堆栈的情况下执行此操作?

3 个答案:

答案 0 :(得分:1)

如果您正在谈论8086(而不是x86系列)那么不,我不相信存在使用堆栈指针的非直接寄存器模式。

基本选项是:

                [BX]  [SI]
<displacement>   or    or
                [BP]  [DI]

当然,如果您没有将其用于其他任何事情,可以将堆栈指针传输到BP,然后使用它:

mov  bp, sp
mov  ax, [bp]
; now check ax

或者,如果您不介意在很短的时间内更改堆栈(但请注意中断是否会导致您出现问题,它们可能会在poppush之间触发) :

pop  ax
push ax
; now check ax

答案 1 :(得分:0)

在任何asm exe的最开始,你声明一个内存块来记录堆栈的顶部

 STAK dw[0]

并使用bx存储堆栈顶部sp

 mov bx,STAK
 mov [bx],sp

然后在需要比较时使用bx与任何寄存器进行比较,bx是指向寄存器

 mov bx,[STAK]
 cmp ax,[bx]

如果需要,可以使用bp而不是bx

答案 2 :(得分:0)

如果在32位保护模式下使用x86系列处理器(80386及更高版本),则在不使用PUSH或POP的情况下将堆栈顶部与AX进行比较非常简单,因为所有通用寄存器都可用作基本索引

CMP    AX, [ESP]      ; compare top of stack with AX
CMP   EAX, [ESP]      ; compare top of stack with EAX

从IA32指令集参考手册中的“表2-1。带ModR / M字节的16位寻址表”,可以使用以下组合。

[BX] + displacment
[BP] + displacement
[SI] + displacement
[DI] + displacement
[BX + SI] + displacement
[BX + DI] + displacement
[BP + SI] + displacement
[BP + DI] + displacement

不幸的是,在16位模式下使用堆栈寄存器不是其中之一(例如在8086上)。这意味着要在不使用PUSH或POP的情况下访问堆栈顶部,必须先将SP寄存器的内容移动到BX,BP,SI或DI,然后使用其中一个寄存器访问堆栈中的顶部元素

您必须注意一些问题。您必须确保寄存器的默认段寄存器与堆栈段寄存器SS匹配,或者您必须明确强制将特定段寄存器与寄存器一起使用。自从我完成任何16位编码以来已经有一段时间了,所以其中一些规则暂时让我失望了。手册一定会包含它们。

BP寄存器默认使用堆栈段SS。它还用于在例程中创建堆栈帧以及索引以获取在堆栈上传递的参数以及本地堆栈变量。

PUSH    BP        ; These two lines are often used to create the stack
MOV     BP, SP    ; at the start of a routine
SUB     SP, #     ; Carve space on the stack for local stack variables

典型的堆栈框架可能看起来像......

[BP + 6]    ; 16-bit parameter
[BP + 4]    ; 16-bit parameter
[BP + 2]    ; return address IP saved on stack
[BP + 0]    ; saved BP on stack
[BP - 2]    ; 16-bit local variable on the stack
[BP - 4]    ; 16-bit local variable on the stack

希望这有帮助。

相关问题