简体   繁体   中英

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?

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 .

As you correctly observe the div family works on the fixed registers a and d , rax and rdx for divq . The a register gets its input from n0 which is aliased to the 0th register, namely a . n1 is a dummy input aliased to d , probably just to ensure that this register is not used for other purposes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM