6

I'm working on ASM intel_syntax noprefix on a mac using gcc, and for some reason I keep getting this error in backend: 32-bit absolute addressing is not supported in 64-bit mode

Does this have something to do with the variables, since, at the moment, I've been using the ASM inline?

Here's my code:

#include <stdio.h>

char c, b;

int main() {

    printf("Give me letter: ");
    scanf(" %c", &c);
    
_

    _asm(   ".intel_syntax noprefix;"
        "xor eax, eax;"     // clear eax
        "mov al, byte ptr [c];" // save c in eax
        "cmp eax, 65;"      // eax ? "A"
        "jl Fin;"       // eax < "A" -> Fin
        "cmp eax, 90;"      // eax ? "Z"
        "jg UpC;"       // eax >= Z -> Up Case
        "add eax, 32;"      // make low case
        "jmp Fin;"      // -> Fin   
    "UpC:   cmp eax, 97;"       // eax ? "a"
        "jl Fin;"       // eax < "a" -> Fin
        "cmp eax, 122;"     // eax ? "z"
        "jg Fin;"       // eax > "z" -> Fin
        "sub eax, 32;"      // make Up Case
    "Fin:   mov byte ptr [b], al;"  // save res in b
        ".att_syntax");
    
    printf("Case changed : %c\n", b);
}
Miguel Guerra
  • 145
  • 1
  • 8
  • The macho abi uses relocatable code, so you can't use absolute addressing. If you want to get a bit more knowledge about how it works here's another question/answer which explains: http://stackoverflow.com/questions/25799551/why-does-this-movq-instruction-work-on-linux-and-not-osx/25804623#25804623, and apple docs: https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachORuntime/index.html#//apple_ref/doc/uid/TP40000895 – l'L'l Mar 07 '16 at 03:32
  • Long story short, use `GOTPCREL` (although not sure about it's use inline)... or compile to `i386` only; take Jester's good advice as well... – l'L'l Mar 07 '16 at 03:47
  • just adding -m32 works, but I don't know if it is the best way to go. – Miguel Guerra Mar 07 '16 at 16:11

1 Answers1

5

Yes, as the error says, on osx you are not allowed to use absolute references which byte ptr [c] assembles to. As a workaround you could try byte ptr c[rip].

Note that it is very bad practice to switch syntax in inline assembly block, you should use -masm=intel compiler switch. Also, gcc inline asm is not supposed to be used like that, normally you use the constraint mechanism to reference arguments.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • 1
    When using gcc's [basic asm](https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html) (as opposed to [extended](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html)), registers are expected to have the same value on output that they have on input. Even accessing globals from basic asm is risky: "Safely accessing C data and calling functions from basic asm is more complex than it may appear. To access C data, it is better to use extended asm." – David Wohlferd Mar 07 '16 at 03:49
  • @DavidWohlferd: Does the same hold true for Clang? – l'L'l Mar 07 '16 at 03:53
  • I just did a simple test, and it looks like clangs handles this correctly. – David Wohlferd Mar 07 '16 at 04:17
  • `[c + rip]` is closer to how `objdump -d -Mintel` prints it. I think this is a duplicate of [Unable to move variables in .data to registers with Mac x86 Assembly](https://stackoverflow.com/q/50205129) (which I updated to include the `.intel_syntax` version), but your answer here is complete and addresses the inline-asm issue. – Peter Cordes May 15 '18 at 23:12