为什么两条箭头线的地址不同?
我在.exe文件中的机器代码中插入蓝线,并期望它在ADD指令之后对同一地址中的值进行AND,但显然AND根据反汇编程序在不同的地址中占用。
我想到这可能是因为地址偏移但是C5 - BE = 7而F8 - EF = 9因此偏移量甚至不匹配,我不知道地址转换之间发生了什么;当机器代码中给出的地址为0x0193A4EF
时,如何计算0x0131132A
?
答案 0 :(得分:5)
您正在使用RIP相对偏移量 解码指令时,反汇编程序对你撒谎 The correct decoding is:
66 01 1D 2A 13 31 01 add WORD PTR [rip+0x131132a],bx
66 81 25 2A 13 31 01 7F FF and WORD PTR [rip+0x131132a],0xff7f
由于RIP始终处于移动状态,因此您需要在下一个指令的开头采用RIP
,而不是完全按照列出的方式应用偏移:6291BE + 7 + 131132A = 193A4EF
。<登记/>
因为下一条指令长度为9个字节,并且您使用相同的RIP偏移量,所以现在需要添加9个字节,因此目标变为:6291C5 + 9 + 131132A = 193 A4F8
,再次与列出的完全相同。
如果您希望两条指令都链接到同一地址,则需要使用不同的RIP偏移量。
始终将使用RIP寻址的指令长度添加到该指令的起始地址,然后应用偏移量。
我想知道为什么你的汇编程序不会自动为你执行此操作。许多汇编程序都有REL
伪寻址模式来解决这个问题
参见例如section 3.3 of the NASM Manual:
在64位模式下,NASM默认会生成绝对地址。 REL关键字使其生成RIP相关地址。
关于REL
的好处是,您不必为自己计算偏移量而烦恼,只需输入您在REL
之后链接到的任何内容的引用。汇编程序将弄清楚其余部分。
其他评论
无论你用什么反汇编程序来分析你的代码都会被破坏
and
值为FF7F
,因为x64为little endian。如果在指令字节中显示7FFF
,您(以及您的反汇编程序)应该知道CPU将读取FF7F,因为最低有效字节首先出现。
请放弃那块垃圾并找一个像样的反汇编程序来分析你的机器代码。
答案 1 :(得分:1)
RIP相对寻址从当前指令的结尾开始计数(下一个指令的开始)。
如果你想到一个非常简单的CPU,它是有道理的:它解码一条指令,然后运行它。当它完成解码时,程序计数器(RIP)指向当前指令的结束(下一条指令的开始),因此当指示当前指令运行时,PC指向下一条指令。
相对跳跃也是一样的。 (例如jmp
,其中rel8 = 0是一个缓慢的无操作。
我认为大多数具有相对跳跃的架构都是这样工作的。还有其他可以访问程序计数器的架构。