我有这样的代码:
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?
发布于 2009-07-25 07:40:20
这看起来像是自修改代码。
它循环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 byteL1+1。当为al=0时,它将第一个JMP替换为下一个语句的JMP,也就是JMP L,所以它循环。当为al=2时,它将第一个JMP替换为跳过2个字节,因此它跳过第二个跳转,因此循环结束。最后edx是12 (5 + 7)
为什么会这样呢?
这里使用的JMP指令是short jumps。它们被编码为2个字节:、EB、,后跟表示要跳转的相对字节数的单个字节。mov指令用 (跳转到下一条指令)或2 (向前跳转2个字节)替换第二个字节。
发布于 2009-07-25 16:47:55
此代码正在自我修改,并且缺少内存栅栏指令。具体发生什么取决于处理器单步执行,以及执行代码时指令高速缓存的满程度,如果这段代码被ISR抢占、发生页错误或其他任何情况,指令高速缓存会发生变化。
https://stackoverflow.com/questions/1181494
复制相似问题