我看到这个指令:
*0x804a1a0(,%eax,4)
我得到了 0x804a1a0 的值并添加了 $eax*4 的值,但这不是代码跳转到的地方。我使用值 0x804a1a0 本身加上 $eax*4 做了同样的事情,它指向其他地方。我如何解释上面的指令?
你说:
我得到了 0x804a1a0 的值并添加了 $eax*4 的值
这是错误的。
我使用值 0x804a1a0 本身加上 $eax*4 做了同样的事情
这也是错误的。
您想要的是首先计算0x804a1a0 + eax*4
,然后查看该内存位置的值。
您提供的代码不是完整的指令,而是AT&T语法中移动/跳转/调用指令的操作数。更具体地说,它被称为有效地址。基本上这是一种间接寻址形式,这意味着将使用操作数给定位置的内存。
有效地址的AT&T语法是:
DISP(BASE,INDEX,SCALE)
这应该解释为:
BASE + INDEX*SCALE + DISP
在你的情况下,
0x804a1a0(,%eax,4)
是真的:
%eax*4 + 0x804a1a0
现在*
根据http://wiki.osdev.org/Opcode_syntax:
相对寻址:在所有跳转和调用指令中默认使用。
要使用绝对寻址,操作数必须以星号 (*) 为前缀。
此外,来自http://en.wikipedia.org/wiki/Addressing_mode:
绝对指令地址的有效地址是未经修改的地址参数本身。
所以最终的地址其实就是 指向的位置eax*4 + 0x804a1a0
。
如果我不得不猜测,我会说它可能是 offset 的跳转/切换表0x804a1a0
。换句话说,代码不会在 offset 处执行eax*4 + 0x804a1a0
,而是读取存储在该位置的地址,然后跳转到该位置(因此它是间接跳转)。
边咆哮:我真的很讨厌AT&T语法。如果您不熟悉汇编,您可能更喜欢 Intel 语法。我认为它更具可读性。您在 Intel 语法中的代码可能是:
jmp dword ptr [0x804a1a0 + eax*4]
假设指令是跳转。