我是装配新手因此不太了解它。我正在使用MASM611和DosBox 0.74。目前,我正在编写一个代码,我必须从另一个标签返回到以前的标签。我也不确定'ret'的语法。同样在调试期间,'ret'出现问题。
代码是这样的:
label1:
cmp bl,bh
je loop
jmp display
loop:
inc count
ret
我希望我的程序返回到label1中跳转到'loop'的那一点。基本上,代码要求使用字母表,当我给它字母表时,程序会进入永久循环(很可能,因为它不起作用)。经过调试后,它可以正常工作直到'ret',但它会失去跟踪或其他东西。
答案 0 :(得分:3)
你不能将ret
与跳跃结合使用,以便在跳跃位置后返回。原因是跳转指令不存储堆栈上的返回地址,这是ret
工作所需的。
使用另一个跳跃:
je loop
back: -- see jmp below which jumps back here
jmp display
loop:
inc count
jmp back
或使用call
指令调用子程序:
jne no_call -- skip the call if condition is not met
call subprog
no_call: -- 'ret' will return back here, as well as the jne above
jmp display
subprog:
inc count
ret
请注意,在特定汇编程序中可能需要更复杂的语法才能声明子程序。
答案 1 :(得分:2)
JCC / JMP不会推送RET的返回地址。正如Ondrej解释的那样,你需要CALL。 (并且没有条件CALL指令)
解决这一分支问题的更有效方法:
label1: ;; jump to display after count += (bl == bh)
cmp bl,bh
jne display ; jump straight there if there's no need to increment
inc count ; preferably keep this in a register; Try to avoid memory for things you modify in a loop.
jmp display
初学者的代码通常会有更多的指令和分支,这是正常的。除了跑得更快,简化分支通常会使人们更容易理解/阅读/跟踪,这绝对是不错的。