为什么12在这个80x86汇编代码中存储在寄存器EAX中?

时间:2009-07-25 07:35:48

标签: assembly x86

我有这段代码:

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?

2 个答案:

答案 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抢占,发生页面错误或任何其他事情,则可能会发生变化。