Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help understanding DIV instruction in x86 inline assembly

While reading through some source code in a GNU project, I came across this bit of inline assembly:

__asm__ (
  "divq %4"
  : "=a" (q), "=d" (r)
  : "0" (n0), "1" (n1), "rm" (d)
);

Here the variables q, r, n0, n1, and d are 64-bit integers. I know enough assembly to get the gist of what this does, but there's some details I'm not certain about.

What I understand:

We're dividing the contents of the RAX register by d, placing the quotient in q, and placing the remainder in r.

What I don't understand

  1. Why are there three inputs here? We only need to input a dividend and a divisor, so what use could there be for 3 inputs?
  2. I can't tell which of the inputs is the dividend. More generally, I don't see anything actually being loaded into the RAX register, so how does it know what to divide by what?
like image 503
Channel72 Avatar asked Oct 14 '22 19:10

Channel72


1 Answers

In the input operands specification:

: "0" (n0), "1" (n1), "rm" (d)

registers "0" and "1" are forced to rax and rdx because of the output specification:

: "=a" (q), "=d" (r)

And the div instruction family wants the numerator in RDX:RAX. The divisor can be in a general purpose register (not otherwise used - ie., not RAX or RDX) or memory, which is specified by the "rm" constraint. Registers RDX, RAX, and the divisor operand make up the 3 inputs.

So this will end up performing the division: n1:n0 / d where n1:n0 is a quantity loaded into rdx:rax.

like image 113
Michael Burr Avatar answered Oct 18 '22 02:10

Michael Burr