Относительные ошибки адресации - 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
Так что мне было интересно, может ли кто-нибудь помочь мне. Я искал Relative Addressing, но я не могу найти ничего, что объясняет на простом языке, что я делаю неправильно.
Я действительно знаю, что инструкция cmp неверна, но я думаю, что я могу это исправить.
Ответы
Ответ 1
64-разрядная версия Mach-O не поддерживает 32-разрядную абсолютную адресацию, поскольку база изображения больше 2 ^ 32.
Обычно вы должны использовать относительную адресацию RIP для доступа к одному элементу памяти. В вашем случае, однако, вы получаете доступ к статическому массиву (массивы, выделенные в разделе данных /bss ) и
как описано в разделе Адресация статических массивов в 64-битном режиме в руководстве Agner Fog Optimization Assembly.
Невозможно получить доступ к статическим массивам с RIP-относительной адресацией и индексным регистром.
Итак, когда NASM обрабатывает ваш код
mov rax, [data_items+rbx*4]
он не может выполнять относительную адресацию RIP, поэтому он пытается 32-разрядный абсолютный + индексный адрес, который не разрешен с 64-битным процессором Mach-O, что заставляет NASM сообщать об ошибке.
Exampels 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]
И затем измените свой код с помощью mov rax, [data_items+rbx*4]
на
mov rax, [rsi+rbx*4]
Поскольку у вас есть delcared DEFAULT REL
, вы можете опустить rel в [rel data_items]
.