0

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

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

push 1
pop ax
cmp ax,1
jz equal

是否可以在不修改堆栈的情况下做到这一点?

4

3 回答 3

1

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

基本选项是:

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

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

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

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

pop  ax
push ax
; now check ax
于 2013-06-25T03:48:38.580 回答
0

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

 STAK dw[0]

并使用 bx 存储栈顶 sp

 mov bx,STAK
 mov [bx],sp

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

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

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

于 2013-06-25T09:29:06.060 回答
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

希望这可以帮助。

于 2013-06-25T12:59:28.317 回答