我有这段代码:
section .data
Foos:
mov ecx,7
mov edx,5
L:
inc edx
sub ecx,1
setZ al ; Set AL to 1 if zero flag, otherwise al=0
shl al,1
mov byte[L1+1],al
L1:
jmp L
lmp L
mov eax,edx
ret
代码末尾的EAX会是什么?
我知道它是12,但为什么答案是12?
答案 0 :(得分:3)
这看起来像是自修改代码。
循环7次,当ecx达到零时,它用不同的JMP指令替换 jmp L 语句,该指令跳转到第二个JMP之后的语句。
Foos:
mov ecx,7
mov edx,5
L:
inc edx
sub ecx,1
setZ al ; set al to 1 if zero flag, otherwise al=0
shl al,1 ; multiply by 2, so al=2 when ecx reaches zero
mov byte[L1+1],al
L1:
jmp L
jmp L
mov eax,edx
ret
魔法在 mov字节[L1 + 1] 中。当al = 0时,它将第一个带有JMP的JMP替换为下一个语句,它再次是JMP L,因此它循环。 当al = 2时,它将第一个JMP替换为跳过2个字节,因此它会跳过第二个跳转,因此循环结束。最后 edx 为12(5 + 7)
为什么?
此处使用的JMP说明是短跳。它们被编码为2个字节: EB 后跟一个字节,表示要跳转的相对字节数。 mov 指令将第二个字节替换为 0 (跳转到下一条指令)或 2 (跳转前2个字节)。
答案 1 :(得分:1)
此代码是自修改并缺少内存栅栏指令。发生的情况取决于处理器步进以及执行代码时指令缓存的完整程度,如果此部分代码被ISR抢占,发生页面错误或任何其他事情,则可能会发生变化。