I’m writing a simple but a little specific program:
Purpose: calculate number from it’s factorial
Requirements: all calculations must be done on gcc inline asm (at&t syntax)
Source code:
#include <iostream>
int main()
{
unsigned n = 0, f = 0;
std::cin >> n;
asm
(
"mov %0, %%eax \n"
"mov %%eax, %%ecx \n"
"mov 1, %%ebx \n"
"mov 1, %%eax \n"
"jmp cycle_start\n"
"cycle:\n"
"inc %%ebx\n"
"mul %%ebx\n"
"cycle_start:\n"
"cmp %%ecx, %%eax\n"
"jnz cycle\n"
"mov %%ebx, %1 \n":
"=r" (n):
"r" (f)
);
std::cout << f;
return 0;
}
This code causes SIGSEV.
Identic program on intel asm syntax (http://pastebin.com/2EqJmGAV) works fine. Why my “AT&T program” fails and how can i fix it?
#include <iostream>
int main()
{
unsigned n = 0, f = 0;
std::cin >> n;
__asm
{
mov eax, n
mov ecx, eax
mov eax, 1
mov ebx, 1
jmp cycle_start
cycle:
inc ebx
mul ebx
cycle_start:
cmp eax, ecx
jnz cycle
mov f, ebx
};
std::cout << f;
return 0;
}
UPD: Pushing to stack and restoring back used registers gives the same result: SIGSEV
Hopefully there are no requirements to use nothing but gcc inline asm to figure it out. You can translate your AT&T example with
nasm, then disassemble withobjdumpand see what’s the right syntax.I seem to recall that
mov 1,%eaxshould bemov $1,%eaxif you mean literal constant and not a memory reference.An answer by @MatsPetersson is very useful regarding the interaction of your inline assembly with the compiler (clobbered/input/output registers). I’ve focused on the reason why you get
SIGSEGV, and reading the address1does answer the question.