Peter Jung
Peter Jung

Reputation: 255

Intel asm syntax with GCC: undefined reference

I am running Ubuntu 64-bit and I have this code:

#include <stdio.h>

int main() {
    int x, y;
    int z = 0;

    printf("Enter two numbers: ");
    scanf("%d %d", &x, &y);

    asm(".intel_syntax noprefix\n"   

       "MOV EAX, _x\n"   
       "MOV ECX, _y\n"   
       "ADD EAX, ECX\n"
       "MOV _z, EAX\n"

       ".att_syntax\n"); 

     printf("%d + %d = %d \n", x, y, z);

    return 0;
}

According to lecture at school it should work, but when I try to compile it with GCC I get this error:

/tmp/ccU4vNLr.o: In function `main':
Jung_79913_211.c:(.text+0x4a): undefined reference to `_x'
Jung_79913_211.c:(.text+0x51): undefined reference to `_y'
Jung_79913_211.c:(.text+0x5a): undefined reference to `_z'
collect2: error: ld returned 1 exit status

I know GCC uses AT&T asm syntax by default, but I need Intel systax at university. So question is, how I can get it working?

Upvotes: 4

Views: 2958

Answers (1)

fuz
fuz

Reputation: 92984

Two things: First, on Linux you don't prefix C symbols with an underscore in assembly, so x, y, z instead of _x, _y, _z. Second, these three variables are automatic variables. You cannot refer to automatic variables like this as no symbols are created for them. Instead, you need to tell the compiler to hand-over these variables into your assembly. You also need to mark the registers eax and ecx as clobbered because your assembly modifies them. Read this documentation for details. Here is how this could work with your code:

asm(
   "MOV EAX, %1\n"   
   "MOV ECX, %2\n"   
   "ADD EAX, ECX\n"
   "MOV %0, EAX\n"
   : "=r" (z) : "r" (x), "r" (y) : "eax", "ecx");

You also need to compile with -masm=intel for this to work as otherwise gcc will insert references to registers in AT&T syntax, causing a compilation error. Even better, learn AT&T syntax if you plan to write a lot of inline assembly for gcc.

Upvotes: 3

Related Questions