I'm trying to learn how to write assembly code and I'm doing it with the help of http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-0-8.pdf. It's an excellent resource and I'm trying to write the code as 64bit for my Mac in Macho64 format.
I've run into some trouble with absolute and relative addressing.
This is my code:
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
and these are the error messages I get:
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
So I was wondering if anyone can help me. I looked up Relative Addressing, but I can't find anything that explains in simple language what I am doing wrong.
I do know the cmp statement is wrong as well, but I think I can fix that myself.
Mach-O 64-bit does not support 32-bit absolute addressing because the image base is greater than 2^32.
Normally you should use RIP relative addressing for accessing a single memory element. In your case however you're accessing a static array (arrays allocated in the data section/bss section) and
as explained in the the section Addressing static arrays in 64 bit mode in Agner Fog's Optimizing Assembly manual.
So when NASM processes your code
it can't do RIP relative addressing so it tries to 32-bit absolute + index address which is not allow with Mach-O 64-bit which causes NASM to report the error.
Exampels 3.11b-3.11d In Agner's manual presents three ways to access static arrays. However, since 64-bit OSX does not allow 32bit absolute addressing (though it's possible in Linux) the first example 3.11b is not possible.
Example 3.11c uses the image base reference point
__mh_execute_header
. I have not looked into this but 3.11d is easy to understand. Uselea
to load the RIP+offset into a register like this:And then change your code using
mov rax, [data_items+rbx*4]
toSince you have delcared
DEFAULT REL
you should be able to ommit the rel in[rel data_items]
.