Question:
I want to practice with assembler inserts. I wanted to write a code to calculate the sum of numbers from 1 to n, implementing it in assembler. However, so far I have not been able to compile even a simple code that writes the value n to sum. Here is the code:
#include <stdio.h>
int sumN(int n)
{
// calculate 1+2+...+n
int sum;
__asm__(
"mov %1, %eax\n\t"
"mov %eax, %0\n\t"
:"=d"(sum)
:"c"(n)
:"%eax");
return sum;
}
int main()
{
for (int i = 1; i < 100; ++i)
{
printf("n: %d sum(n): %d\n",i,sumN(i) );
}
return 0;
}
However, the g ++ compiler throws an error
main.cpp: 11: 11: error: invalid 'asm': operand number missing after% -letter: "% eax");
^
main.cpp: 11: 11: error: invalid 'asm': operand number missing after% -letter.
I thought that the problem was that I did not specify all the registers that I use, so I rewrote the code a little:
#include <stdio.h>
int sumN(int n)
{
// calculate 1+2+...+n
int sum;
__asm__(
"mov %1, %eax\n\t"
"mov %eax, %0\n\t"
:"=d"(sum)
:"c"(n)
:"%eax","%edx","%ecx");
return sum;
}
int main()
{
for (int i = 1; i < 100; ++i)
{
printf("n: %d sum(n): %d\n",i,sumN(i) );
}
return 0;
}
However, this code does not compile either, gcc gives an error
main.cpp: 11: 25: error: 'asm' operand has impossible constraints
: "% eax", "% edx", "% ecx");
Tell me what is the error and how to fix it? PS was guided by this article
Answer:
In the assembly code itself, the %
sign must be escaped, i.e. write %%eax
, but in a clobber list, on the contrary, the %
sign is optional.
int sumN(int n)
{
// calculate 1+2+...+n
int sum;
__asm__(
"mov %1, %%eax\n\t"
"mov %%eax, %0\n\t"
:"=d"(sum)
:"c"(n)
:"eax");
return sum;
}
...
$ gcc test.c -m32 -o test
$ ./test
n: 1 sum(n): 1
...
n: 99 sum(n): 99
By the way, keep in mind that about compiling for x86-64, writing to eax clears the high-order bits of rax. This will need to be reflected in the clobber list.