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
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.