gpt4 book ai didi

assembly - 为什么在 NASM 中使用 RIP 相对寻址?

转载 作者:行者123 更新时间:2023-12-02 20:06:26 27 4
gpt4 key购买 nike

我有一个适用于 Mac OS X 的程序集 hello world 程序,如下所示:

global _main


section .text

_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msg]
mov rdx, msg.len
syscall

mov rax, 0x2000001
mov rdi, 0
syscall


section .data

msg: db "Hello, World!", 10
.len: equ $ - msg

我想知道 lea rsi, [rel msg] 行。为什么 NASM 强制我这样做?据我了解,msg只是指向可执行文件中某些数据的指针,并执行 mov rsi, msg将该地址放入 rsi 。但是如果我替换行 lea rsi, [rel msg]使用 ,NASM 会抛出此错误(注意:我使用命令 nasm -f macho64 hello.asm ):

hello.asm:9: fatal: No section for index 2 offset 0 found

为什么会发生这种情况? lea有何特别之处?那mov不能做吗?我怎么知道何时使用每一个?

最佳答案

What is so special about lea that mov can't do?

mov reg,imm立即常量加载到其目标操作数中。立即常量直接编码在操作码中,例如如果 someVar 的地址为 0x00ABCDEF,则 mov eax,someVar 将被编码为 B8 EF CD AB 00。 IE。要使用 imm 作为 msg 的地址来编码这样的指令,您需要知道 msg 的确切地址。在与位置无关的代码中,您事先并不知道它。

mov reg,[表达式] 加载表达式 描述的地址处的值。 x86指令的复杂编码方案允许有相当复杂的表达式:一般来说它是reg1+reg2*s+displ,其中s可以是0,1,2,4,reg1reg2可以是通用寄存器或零,displ是立即位移。在64位模式下,表达式可以有另一种形式:RIP+displ,即相对于下一条指令计算地址。

lea reg,[表达式] 使用所有这些计算地址的复杂方法将地址本身加载到 reg 中(与 mov,它取消引用计算出的地址)。因此,在编译时不可用的信息,即 RIP 中的绝对地址,可以在不知道其值的情况下编码在指令中。 nasm 表达式 lea rsi,[rel msg] 被翻译成类似

    lea rsi,[rip+(msg-nextInsn)]
nextInsn:

它使用相对地址msg-nextInsn而不是msg的绝对地址,从而允许汇编器不知道实际地址但仍然对指令进行编码。

关于assembly - 为什么在 NASM 中使用 RIP 相对寻址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31234395/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com