Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intel asm syntax with GCC: undefined reference

Tags:

c

gcc

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?

like image 581
Peter Jung Avatar asked Sep 06 '25 03:09

Peter Jung


1 Answers

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.

like image 142
fuz Avatar answered Sep 09 '25 02:09

fuz