gpt4 book ai didi

macos - 汇编程序错误 : Mach-O 64 bit does not support absolute 32 bit addresses

转载 作者:行者123 更新时间:2023-12-04 18:14:25 26 4
gpt4 key购买 nike

所以我在我的 mac 上学习 x86_64 nasm 程序集是为了好玩。在 hello world 和一些基本的算术之后,我尝试从 this site 复制一个稍微高级一点的 hello world 程序。并为 64 位英特尔修改它,但我无法摆脱这个错误消息:hello.s:53: error: Mach-O 64-bit format does not support 32-bit absolute addresses .这是我用来组装和链接的命令:nasm -f macho64 hello.s && ld -macosx_version_min 10.6 hello.o .这是相关的行:

cmp rsi, name+8

rsi 是我在循环中用于索引的寄存器,而 name 是为用户输入保留的四字词,即名称,此时已经写入。

这是代码的一部分(要查看其余部分,请单击链接并转到底部,唯一不同的是我使用的是 64 位寄存器):
loopAgain:
mov al, [rsi] ; al is a 1 byte register
cmp al, 0x0a ; if al holds an ascii newline...
je exitLoop ; then jump to label exitLoop

; If al does not hold an ascii newline...
mov rax, 0x2000004 ; System call write = 4
mov rdi, 1 ; Write to stdout = 1
mov rdx, 1 ; Size to write
syscall

inc rsi

cmp rsi, name+8 ; LINE THAT CAUSES ERROR
jl loopAgain

最佳答案

cmp指令不支持 64 位立即数操作数。因此,您不能在其操作数之一中放置 64 位立即地址引用 - load name+8存入一个寄存器,然后与该寄存器进行比较。

您可以在 Intel ISA manual 中查看允许使用哪些指令编码。 (警告:巨大的PDF)。正如您在 CMP 条目中看到的,有 CMP r/m32,
imm32
CMP r/m64,
imm32
编码,允许将 32 位立即数与 32 位和 64 位寄存器进行比较,但不能比较 CMP r/m64, imm64 .然而,有一个 MOV r64, imm64编码。

或者更好的是,使用相对于 RIP 的 LEA:使用 default rel然后 lea r64, [name+8] .这比 mov r64, imm64 更高效、更小.

由于nasm正在崩溃,MOV rcx, name+8的失败只是 nasm 中的一个错误。请向 nasm 开发人员报告(在确保您使用的是最新版本的 nasm 之后;另外,检查 this patch 是否不能解决问题)。但无论如何,一种解决方法是在 name 的末尾添加一个符号。 :

name:
resb 8
name_end:

现在只需使用 MOV rcx, name_end .这样做的好处是当 name的大小时不需要更新所指对象。变化。或者,您可以使用不同的汇编程序,例如 clang 或 GNU binutils 汇编程序。

评论中的讨论指出 Linux 可以将符号地址用作 32 位立即数。这仅适用于与低 2GiB 虚拟地址空间中的基地址链接的非 PIE 可执行文件。但是MacOS选择把镜像基地址放在4GiB以上所以不能用 mov r32, imm32cmp r64, sign_extended_imm32带有符号地址。

关于macos - 汇编程序错误 : Mach-O 64 bit does not support absolute 32 bit addresses,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6577482/

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