在MS-DOS下的汇编程序中堆栈

时间:2012-05-18 08:02:21

标签: assembly x86 stack nasm

我正在尝试学习一些汇编程序代码;具体如何使用堆栈及其工作方式等。但是,当我使用下面的代码时遇到错误:

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。 任何有关我的错误的帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

没有使用NASM,但我认为你处于16位模式,默认使用16位寄存器弹出,所以你不能使用啊。当您将0x42推送到16位值(0x0042)的堆栈时。使用pop ax然后设置啊:

是安全的
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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

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

push dword 0x42