I have the following code:
#include <stdio.h>
void main(){
int x=0, y=0,i=100;
for (;i<1000; i++,x+=32){
if (x == 25*32) {
y+=32;
asm volatile("pushl %%eax\n\t"
"movl $0, %%eax\n\t"
"popl %%eax\n\t"
:"=a"(x)
:"a"(0)
);
}
printf("%d %d\n", x, y);
}
}
Basically, what I want to do is, set the variable x to 0 but I don’t quite understand what the assembly code does, and it actually does set x to 0 but I’m not sure whats going on. can somebody explain what’s going on? (just for the sake of learning assembly and C).
Here is what your asm construct says:
"=a"(x), you tell the compiler that the assembly will write (=) to the %eax (a) register, and you want the compiler to assign that result to x ((x))."a"(0), you tell the compiler you want it to put a 0 ((0)) in %eax (a), and the assembly will read it.push %%eaxsaves %eax on the stack,movl $0, %%eaxputs 0 in %eax, andpopl %%eaxrestores the saved value to %eax.So, what happens is:
So, this works, but it is inefficient. You can get the same effect with this:
What this says is:
=tells the compiler these instructions will write a result.rsays the result will be written to a register, but the compiler gets to pick the register.[MyName]tells the compiler to change%[MyName], where it appears in the assembly code, to the name of the register the compiler picks.(x)says to use the value in the register after the assembly code as the new value of x.movl $0, %[MyName]says to move 0 to the register named by %[MyName].Because the compiler gets to pick the register, you do not have to save and restore it in the assembly language. The compiler is responsible for making sure it does not need that register for anything else.
Being able to name the operands as I have done with
[MyName]is a new feature in GCC. If your version does not have it, you can do this instead:Without names, each operand gets a number, starting at 0, and incremented in the order the operands appear in the input/output specifiers. Since we had only one operand, it was %0.