Author Topic: Macho64 32-bit addresses problem  (Read 6863 times)

Offline mystor

  • New Member
  • Posts: 1
Macho64 32-bit addresses problem
« on: January 07, 2015, 05:44:14 PM »
I'm having a problem getting some code to assemble on MachO-64. When I try to build this code:
Code: [Select]
        default rel
label:
        db 1
        db 2
        db 3

global start
start:
        mov rax, 1
        mov rax, [rax+label]
It fails to build on MachO-64. It seems to build fine on ELF-64, and if I swap `rax` for `eax`, and build on MachO, it assembles fine.

The error is `small_macho_test.asm:10: error: Mach-O 64-bit format does not support 32-bit absolute addresses`

After doing some research, I discovered that usually this error is solved by `default rel`, but it doesn't seem to do anything in this case. Any hints on how to fix my problem?

(command is `nasm -f macho64 small_macho_test.asm`)

EDIT: I'm aware that the example code is totally wrong in terms of what memory it is accessing, but afaik that shouldn't be causing this problem.
« Last Edit: January 07, 2015, 05:49:04 PM by mystor »

Offline daveshields

  • Jr. Member
  • *
  • Posts: 4
Re: Macho64 32-bit addresses problem
« Reply #1 on: January 15, 2015, 01:37:21 PM »
For ELF the following is ok:
global start
start:
        mov rax, 1
        mov rax, [rax+label]
However, for macho-64 you need to write
start:
...
      mov rax,1
      mov rax,[rel rax+label]
ELF binaries reside in the lower 2GB of the address space, so you can give an address as a 32-bit value.

However, for mach-64, the address space used is much higher than 2GB, so you can NOT use such 32-bit values. This is the reason you are getting the error message.

What you need to do is to use RIP (Relative to Instruction Pointer) addressing mode, in which a reference to date is, like a reference to a program label, expressed as an offset from
the Instruction Pointer, which contains the address of the next instruction to be executed.

The 'rel' prefix directs NASM to change the "absolute" addresses to addresses relative to the IP.

You can also use the 'default rel' instruction to request this be done everywhere.

I've been trying to sort out this issue in a porting effort I'm doing right now trying to move some code to Apple's OSX.

There is *very* little about this topic to be found on the net, which suggests that the number of folks writing assembly language for OSX is much
smaller than the small number who write such code for x86-64.

thanks,dave

Offline daveshields

  • Jr. Member
  • *
  • Posts: 4
Re: Macho64 32-bit addresses problem
« Reply #2 on: January 15, 2015, 01:48:02 PM »
Oops, I just realized I left something out.

Consider the following for macho-64

lbl:
...
    mov rdx,lbl
in which you want to move the address of label lbl -- not the contents of memory at the label -- to register rdx.

This yields the 32-bit error message, so you need to introduce a temporary location.

lbl:
...
    segment .data
lbl.a  dq lbl
    segment .text
...
   mov rax,[rel lbl.a]  ; load address of label lbl from memory location lbl.a

thanks,dave