所以,我正在乱搞集会,偶然发现了奇怪的事情。在写任何东西之前,我将寄存器设置为这些值:
AX 0000, BX 0000, SP 00FD.
让我们说,我们编写简单的代码,增加寄存器AX和BX:
A100
INC AX
CALL 0200
A200
INC BX
RETN
写完之后,我试着看一下使用T命令逐个执行命令时寄存器的变化。第一次,它增加AX
,移至0200
,增加BX
并返回。这是奇怪的一点:当它返回时,它执行命令:
ADD [BX+SI],AX
,然后再次致电0200
。
当它再次调用0200
时,它会自行重复,但现在,当它返回时,它会返回CALL 0100
命令(而不是CALL 0200
)并再次增加AX
等等。为什么会这样?
我有完整输出的图像,也许这有助于更好地理解我的问题?: http://s18.postimg.org/wt6eracg9/Untitled.png
答案 0 :(得分:3)
根据您的屏幕截图,您的代码似乎是这样(填充nop
,用udcli
反汇编):
echo 40 e8 fc 00 01 00 e8 f7 00 e8 f4 ff x{1..244} 43 c3 | sed 's/x[0-9]*\>/90/g' | udcli -o 0x100 -x -16
0000000000000100 40 inc ax 0000000000000101 e8fc00 call word 0x200 0000000000000104 0100 add [bx+si], ax 0000000000000106 e8f700 call word 0x200 0000000000000109 e8f4ff call word 0x100 000000000000010c *** never reached *** 0000000000000200 43 inc bx 0000000000000201 c3 ret
代码流程如下,逐行:
0000000000000100 40 inc ax
ax
会增加。
0000000000000101 e8fc00 call word 0x200
返回地址0x104被推送到堆栈,ip
(指令指针)被设置为0x200。
0000000000000200 43 inc bx
bx
会增加。
0000000000000201 c3 ret
接近返回,即从堆栈中弹出ip
。新的ip
将为0x104。
0000000000000104 0100 add [bx+si], ax
将ax
的值添加到[bx+si]
处的字值。
0000000000000106 e8f700 call word 0x200
返回地址0x109被推送到堆栈,ip
(指令指针)设置为0x200。
0000000000000200 43 inc bx
bx
会增加。
0000000000000201 c3 ret
接近返回,即从堆栈中弹出ip
。新ip
将为0x109。
0000000000000109 e8f4ff call word 0x100
返回地址0x10c被推送到堆栈,ip
(指令指针)被设置为0x100。所以这实际上是一个无限的递归函数,并且会耗尽堆栈。
所以你的问题是你没有在CALL 0200
之后定义代码。碰巧有01 00
(add [bx+si], ax
)并且在返回后它将被执行,并且在其它未定义的指令之后。
我的建议:尽快下载任何体面的汇编程序(NASM,YASM,FASM ......)并且不要破坏你的生活,试图用DEBUG编写汇编代码。尝试使用DEBUG编写汇编程序是一种注定要失败的尝试。
答案 1 :(得分:2)
可能的原因是你没有退出,你没有使用DOS的0x4c
服务,程序绑定代码并开始执行随机命令或执行流命中一些{{ 1}}没有使用ret
的指令,然后会出现意外行为。