I am currently writing a simple C compiler, that takes a .c file as input and generates assembly code (X86, AT&T syntax). Everyting is good, but when I try to execute a IDIVQ instruction, I get a floating-point exception. Here's my input:
int mymain(int x){ int d; int e; d = 3; e = 6 / d; return e; }
And here is my generated code:
mymain: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 movq %rsp, %rbp .cfi_offset 6, -16 .cfi_def_cfa_register 6 movq %rdi, -40(%rbp) movq $3, -8(%rbp) movq $6, %rax movq -8(%rbp), %rdx movq %rdx, %rbx idivq %rbx movq %rax, -16(%rbp) movq -16(%rbp), %rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1: .size mymain, .-mymain
According to http://www.cs.virginia.edu/~evans/cs216/guides/x86.html, idivq %rbx should produce 6/d (the quotient) in %rax. But I'm getting a floating-point exception, and I can't seem to find the problem.
Any help will be much appreciated!
idiv executes signed division. idiv divides a 16-, 32-, or 64-bit register value (dividend) by a register or memory byte, word, or long (divisor). The size of the divisor (8-, 16- or 32-bit operand) determines the particular register used as the dividend, quotient, and remainder.
The DIV instruction divides unsigned numbers, and IDIV divides signed numbers. Both return a quotient and a remainder.
“longword”is 32 bits, a quadword” is 64. d) Do a cqto instruction (with no operands) to sign-extend it to. rdx. cqto stands for “convert quadword to octword.”
The return address is just the address directly after the parameters to the call instruction. To see what the return address is in your example above, you'd have to look at the stack as soon as the program gets into the procedure at 0x4012d0.
The first part of Mysticials answer is correct, idiv
does a 128/64 bit division, so the value of rdx
, which holds the upper 64 bit from the dividend must not contain a random value. But a zero extension is the wrong way to go.
As you have signed variables, you need to sign extend rax
to rdx:rax
. There is a specific instruction for this, cqto
(convert quad to oct) in AT&T and cqo
in Intel syntax. AFAIK newer versions of gas accept both names.
movq %rdx, %rbx cqto # sign extend rax to rdx:rax idivq %rbx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With