- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个适用于 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
thatmov
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,reg1
和reg2
可以是通用寄存器或零,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/
我是一名优秀的程序员,十分优秀!