0

我正在尝试学习一些汇编代码;特别是如何使用堆栈以及它是如何工作的等等。但是,当我使用下面的代码时,我遇到了一个错误:

entry:
    push 0x42
    call teststack
    jmp hang

hang:
    jmp hang

teststack:
    mov ah, 0x0e
    pop al
    mov bh, 0x00
    mov bl, 0x04
    mov cx, 0x01
    int 10h
    ret

我要做的是将数字 42(生命,宇宙,一切:D)传递到我的测试堆栈程序中,它将打印 Ascii 0x42(我认为是大写 B)。我的问题是编译器错误,对于读取pop al的行:

**error: invalid combination of opcode and operands**

我在 Windows 98 虚拟机中使用 NASM。对我的错误的任何帮助将不胜感激。

4

3 回答 3

1

从来没有使用过 NASM,但我认为您处于 16 位模式,并且 pop 默认使用 16 位寄存器,所以您不能使用啊。当您将 0x42 推入堆栈时,这是一个 16 位值 (0x0042)。使用 pop ax 然后设置 ah 是安全的:

entry:
    push 0x42
    call teststack
    jmp hang

hang:
    jmp hang

teststack:
    pop ax           ; ax = 0x0042
    mov ah, 0x0e     ; ax = 0x0e42
    mov bh, 0x00
    mov bl, 0x04
    mov cx, 0x01
    int 10h
ret
于 2012-05-18T08:47:01.530 回答
1

如果您将某个值压入堆栈(即 0x42 值),您的堆栈将包含一个值 [0x42]。接下来,您使用将返回地址存储在堆栈上的调用指令,因此堆栈现在包含 [ret_addr, 0x42]。

第一条子程序指令弹出值(出乎意料的是它是 ret-addr 而不是 0x42),然后执行其他操作并跳转(ret 指令)到从堆栈弹出的地址(0x42 ...)。

您可以使用 BP 寄存器中的堆栈指针副本来读取存储在堆栈中的值并使用 RET N 指令从子程序返回(高级语言使用类似的 sheme)。

于 2012-05-18T14:15:55.920 回答
0

用 push 你必须像这样指定大小

push dword 0x42
于 2012-05-18T08:06:45.283 回答