Относительные ошибки адресации - Mac 10.10

Я пытаюсь научиться писать ассемблерный код и делаю это с помощью http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-0-8.pdf. Это отличный ресурс, и я пытаюсь написать 64-битный код для моего Mac в формате Macho64.

У меня возникли проблемы с абсолютной и относительной адресацией.

Это мой код:

    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 также неверно, но я думаю, что могу исправить это сам.

1 ответ

Решение

64-битное Mach-O не поддерживает абсолютную 32-битную адресацию, потому что база изображений больше 2 ^ 32.

Обычно вы должны использовать относительную адресацию RIP для доступа к одному элементу памяти. Однако в вашем случае вы обращаетесь к статическому массиву (массивы, размещенные в разделе данных / разделе bss) и
как описано в разделе " Адресация статических массивов в 64-битном режиме" в Руководстве по оптимизации сборки Agner Fog.

Невозможно получить доступ к статическим массивам с RIP-относительной адресацией и регистром индекса.

Поэтому, когда NASM обрабатывает ваш код

mov rax, [data_items+rbx*4]

он не может выполнить относительную адресацию RIP, поэтому он пытается использовать 32-битный абсолютный + индексный адрес, что недопустимо для 64-битного Mach-O, в результате чего NASM сообщает об ошибке.

Примеры 3.11b-3.11d В руководстве Агнера представлены три способа доступа к статическим массивам. Однако, поскольку 64-битная OSX не допускает 32-битную абсолютную адресацию (хотя это возможно в Linux), первый пример 3.11b невозможен.

Пример 3.11c использует базовую опорную точку изображения __mh_execute_header, Я не смотрел на это, но 3.11d легко понять. использование lea загрузить смещение RIP+ в регистр следующим образом:

lea rsi, [rel data_items]

А затем измените свой код, используя mov rax, [data_items+rbx*4] в

mov rax, [rsi+rbx*4]

С тех пор как вы удалились DEFAULT REL Вы должны быть в состоянии опустить Rel в [rel data_items],

Другие вопросы по тегам