[英]Why call and ret functions work like this in assembly?
所以,我在弄乱装配,偶然发现了奇怪的东西。 在写任何东西之前,我将寄存器设置为以下值:
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
根据您的屏幕截图,您的代码似乎是这样的(用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编写汇编程序注定会失败。
可能的原因是您没有退出,没有使用DOS的0x4c
服务,并且程序绑定了代码并开始执行随机命令,或者执行流程命中了一些ret
指令,其中不使用任何call
,因此然后会表现异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.