在 OSX x64 程序集中使用 RIP 相对寻址 [英] Using RIP-relative addressing in OSX x64 assembly

查看:43
本文介绍了在 OSX x64 程序集中使用 RIP 相对寻址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 OSX 的 x86-64 汇编代码中制作一个基本的 printf 示例,这是我的第一个版本:

section .datamsg db '你好', 0Ah节.text外部_printf全局_main_主要的:子 rsp, 8mov rdi, msg移动 rax, 0调用_printf添加 rsp, 8退

所以这段代码将msg的绝对地址移动到rdi作为_printf的第一个参数,然后gcc抱怨缺少与位置无关的代码.二进制文件仍然有效:

→ nasm -f macho64 new.asm &&gcc -m64 -o new new.o &&./新的ld:警告:PIE 已禁用.绝对寻址(可能是 -mdynamic-no-pic)在代码签名的 PIE 中是不允许的,但在 new.o 的 _main 中使用.要修复此警告,请勿使用 -mdynamic-no-pic 编译或使用 -Wl,-no_pie 链接你好

因此,当我使用 [rel ...] nasm 语法更改代码以使用 RIP 相对寻址时,警告消失了,但可执行文件现在出现段错误:

section .datamsg db '你好', 0Ah节.text外部_printf全局_main_主要的:子 rsp, 8mov rdi, [rel msg]移动 rax, 0调用_printf添加 rsp, 8退

当我编译并运行它时:

→ nasm -f macho64 new.asm &&gcc -m64 -o new new.o &&./新的zsh:分段错误./新

有人知道出了什么问题吗?

解决方案

问题是原来的mov rdi,msgmsg的内存地址加载到rdi 在汇编时.

当改成mov rdi, [rel msg]时,产生的代码使用msg中的值作为相对地址,调试时看到:

程序接收到信号 EXC_BAD_ACCESS,无法访问内存.原因:KERN_INVALID_ADDRESS 地址:0x00000a6f6c6c6568

注意地址如何包含来自msg0x00000a

的字节.

正确的解决方案是在运行时使用lea指令加载msg的有效RIP相对地址,如下所示:

lea rdi, [rel msg]

I was trying to make a basic printf example in x86-64 assembly code for OSX, here's my first version:

section .data
msg db 'hello', 0Ah

section .text
extern _printf

global _main
_main:
  sub rsp, 8

  mov rdi, msg
  mov rax, 0
  call _printf

  add rsp, 8

  ret

So this code is moving the absolute address of msg into rdi for the first argument to _printf, and gcc then complains about the lack of position-independent code. The binary still works though:

→ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from new.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
hello

So when I change the code to use RIP-relative addressing, using the [rel ...] nasm syntax, the warning disappears but the executable now seg faults:

section .data
msg db 'hello', 0Ah

section .text
extern _printf

global _main
_main:
  sub rsp, 8

  mov rdi, [rel msg]
  mov rax, 0
  call _printf

  add rsp, 8

  ret

And when I compile and run it:

→ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new
zsh: segmentation fault  ./new

Does anyone know what's going wrong?

解决方案

The problem is that the original mov rdi, msg loaded the memory address of msg into rdi at assemble time.

When it was changed to mov rdi, [rel msg], this produced code which used the value in msg as the relative address, as seen when debugging:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000a6f6c6c6568

Notice how the address contains the bytes from msg, 0x00000a<olleh>.

The correct solution is to use the lea instruction to load the effective RIP-relative address of msg at runtime, like so:

lea rdi, [rel msg]

这篇关于在 OSX x64 程序集中使用 RIP 相对寻址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆