在执行JMP命令后,程序不会返回到其被调用的位置

时间:2019-04-12 18:09:26

标签: assembly nasm

我正在尝试为DOSBOX编写一个简单的图形引擎,并且运行得很好,我一直在使用https://github.com/adamsmasher/sokobanDOS/中的一些代码
我的问题是,在我调用JMP命令转到drawpixel之后,程序没有返回到main,至少我认为它没有。在drawpixel之后,应该返回到我自己测试过的文本,并且可以正常工作。
我是组装的新手,所以我真的不知道自己在做什么。

jmp initgraph

main:
    MOV CX, 320
    JMP drawpixel
    JMP returntext
    JMP main

initgraph:
    MOV AX, 13h
    INT 10h
    MOV CX, 0
    JMP main

returntext:
    MOV AX, 0x03
    INT 0x10
    RET

drawpixel:
    MOV AX, 0A000h
    MOV ES, AX
    MOV AX, CX
    MOV DI, AX
    MOV DL, 0xE
    MOV [ES:DI], DL

它应该可以真正快速显示一个像素并返回到文本模式,但是它会冻结并且不返回文本。

1 个答案:

答案 0 :(得分:2)

问题是您使用的是JMP而不是CALL

使用JMP(或其任何条件变量)时,您正在指示CPU用用操作数编码的立即数或计算值替换当前指令指针。没有提供任何跟踪您所在位置的信息。

使用CALL操作时,以下操作码的地址被压入堆栈,SP递减适当的堆栈宽度,并放置调用中的立即数/计算值进入指令指针。这使您可以使用RET指令返回到先前的执行位置。

使用CALL,进入图形模式,绘制像素,等待键,返回文本模式然后退出回到DOS的示例代码如下:

org 100h

main:
    CALL initgraph
    MOV CX, 320
    CALL drawpixel
    CALL waitforkey
    CALL returntext

    MOV AX, 4C00h               ; Exit to DOS returning exit code 00h
    INT 21h

waitforkey:
    MOV AH, 0                   ; Int 16h/AH=0 get key BIOS call
    INT 16h
    RET

initgraph:
    MOV AX, 13h
    INT 10h
    MOV CX, 0
    RET

returntext:
    MOV AX, 0x03
    INT 0x10
    RET

drawpixel:
    MOV AX, 0A000h
    MOV ES, AX
    MOV AX, CX
    MOV DI, AX
    MOV DL, 0xE
    MOV [ES:DI], DL
    RET