【问题标题】:Relative Addressing errors - Mac 10.10相对寻址错误 - Mac 10.10
【发布时间】:2015-01-11 16:25:26
【问题描述】:

我正在尝试学习如何编写汇编代码,并在 http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-0-8.pdf 的帮助下完成。这是一个很好的资源,我正在尝试以 Macho64 格式为我的 Mac 编写 64 位代码。

我在绝对和相对寻址方面遇到了一些麻烦。

这是我的代码:

    DEFAULT REL
;PURPOSE:   This program finds the maximum number of a set of data items
;

;VARIABLES: The registers have the following uses
;
;   rbx - Holds the index of the data item being examined
;   rdi - Largest data item found
;   rax - Current data item
;
;   The following memory locations are used:
;
;   data_items - contains the item data. A 0 is used to terminate the data
;

global _main

section .data
    data_items: dw  3,67,34,222,45,75,54,34,44,33,22,11,66,0
    ;These are the data items

section .text

_main:              
    mov rdi, 0          ;move 0 into index register
    mov rax, [data_items+rbx*4] ;load the first data byte
    mov rdi, rax        ;since this is the first item, eax is biggest

start_loop:         ;start loop
    cmp 0, rax          ;check to see if we've hit the end
    je loop_exit
    inc rdi
    mov rax, [data_items+rbx*4]
    cmp rdi, rax
    jle start_loop

    mov rdi,rax
    jmp start_loop    

loop_exit:
    mov rax, 0x2000001          ;1 is the exit() syscall
    syscall

这些是我收到的错误消息:

Samuels-MBP:Starting sam$ make
src/maximum.s:26: error: Mach-O 64-bit format does not support 32-bit absolute addresses
src/maximum.s:30: error: invalid combination of opcode and operands
src/maximum.s:33: error: Mach-O 64-bit format does not support 32-bit absolute addresses

所以我想知道是否有人可以帮助我。我查找了相对寻址,但找不到任何用简单语言解释我做错了什么的东西。

我也知道 cmp 语句是错误的,但我想我可以自己解决这个问题。

【问题讨论】:

标签: macos assembly nasm x86-64


【解决方案1】:

Mach-O 64-bit does not support 32-bit absolute addressing because the image base is greater than 2^32.

通常您应该使用 RIP 相对寻址来访问单个内存元素。但是,在您的情况下,您正在访问一个静态数组(在数据部分/bss 部分中分配的数组)和
Addressing static arrays in 64 bit mode in Agner Fog's Optimizing Assembly manual 部分所述。

无法使用 RIP 相对寻址和索引寄存器访问静态数组。

所以当 NASM 处理你的代码时

mov rax, [data_items+rbx*4]

它不能进行 RIP 相对寻址,因此它尝试使用 32 位绝对 + 索引地址,这在 Mach-O 64 位中是不允许的,这会导致 NASM 报告错误。

示例 3.11b-3.11d 在 Agner 的手册中介绍了三种访问静态数组的方法。但是,由于 64 位 OSX 不允许 32 位绝对寻址(尽管在 Linux 中可以),所以第一个示例 3.11b 是不可能的。

示例 3.11c 使用图像基础参考点__mh_execute_header。我没有研究过这个,但 3.11d 很容易理解。使用lea 将 RIP+offset 加载到这样的寄存器中:

lea rsi, [rel data_items]

然后使用 mov rax, [data_items+rbx*4] 将您的代码更改为

mov rax, [rsi+rbx*4]

既然你已经删除了DEFAULT REL,你应该可以省略[rel data_items]中的rel。

【讨论】:

  • 非常感谢。这正是答案。
  • @LordWindy,对于第 30 行的错误,请将 cmp 0, rax 更改为 cmp rax, 0
猜你喜欢
  • 2013-04-07
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 2015-02-15
相关资源
最近更新 更多