For entertainment, I am learning gnu extended assembly using AT&T syntax for x86 with a 32bit Linux target. I have just spent the last three hours coding two possible solutions to my challenge of swapping the values of two integer variables a
and b
, and neither of my solutions completely solved my problem. First, let's look at my TODO obstacle in some more detail:
int main()
{
int a = 2, b = 1;
printf("a is %d, b is %d
", a, b);
// TODO: swap a and b using extended assembly, and do not modify the program in any other way
printf("a is %d, b is %d
", a, b);
}
After reading this HOWTO, I wrote the following inline extended assembler code. Here is my first attempt at swapping the integers:
asm volatile("movl %0, %%eax;"
"movl %1, %%ecx;"
"movl %%ecx, %0;"
: "=r" (a)
: "r" (b)
: "%eax", "%ecx");
asm volatile("movl %%eax, %0;"
: "=r" (b)
: "r" (a)
: "%eax", "%ecx");
My reasoning was that to set a = b, I needed an extended assembly call that was separated from the assembly to set b = a. So I wrote the two extended assembly calls, compiled my code, i.e., gcc -m32 asmPractice.c, and ran a.out. The results were as follows:
a is 2, b is 1
a is 1, b is 1
Seeing how that did not work properly, I then decided to combine the two extended assembler calls, and wrote this:
asm volatile("movl %0, %%eax;"
"movl %1, %%ecx;"
"movl %%ecx, %0;"
"movl %%eax, %1;"
: "=r" (a)
: "r" (b));
After recompiling and linking, my code still does not correctly swap both values. See for yourself. Here are my results:
a is 2, b is 1
a is 1, b is 1
See Question&Answers more detail:
os