相对寻址错误 - Mac 10.10

Lor*_*ndy 4 macos assembly x86-64 nasm

我正在尝试学习如何编写汇编代码,我是在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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

我知道cmp声明也是错误的,但我想我可以自己解决这个问题.

Z b*_*son 5

Mach-O 64位不支持32位绝对寻址,因为映像基数大于2 ^ 32.

通常,您应该使用RIP相对寻址来访问单个内存元素.但是,在您的情况下,您正在访问静态数组(在数据部分/ bss部分中分配的数组),并在Agner Fog的优化汇编手册中的64位模式寻址静态数组
一节中进行了说明.

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

因此,当NASM处理您的代码时

mov rax, [data_items+rbx*4]
Run Code Online (Sandbox Code Playgroud)

它不能进行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 +偏移量加载到这样的寄存器中:

lea rsi, [rel data_items]
Run Code Online (Sandbox Code Playgroud)

然后使用mov rax, [data_items+rbx*4]to 更改代码

mov rax, [rsi+rbx*4]
Run Code Online (Sandbox Code Playgroud)

既然你有delcared DEFAULT REL你应该能够省略rel [rel data_items].