Reputation: 255
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
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