nto*_*tos 2 assembly x86-64 integer-division
假设您想使用Gas将 -198077031546722079779 除以 23 。由于这个股息比较大%rax,你怎么投入呢 %rdx:%rax?我读过的所有关于汇编的书都避免idiv用例子来说明,所以我迷失了。
您可能知道,您将高位放入,rdx将低位放入。rax
如果您尝试在程序中使用该数字作为常量,那么是的,十六进制是一种可能的拆分方法。我使用calc对其进行转换,添加 2^128 将其表示为无符号二进制补码数,然后使用printf("%x")将其打印为十六进制。结果是0xfffffffffffffff543210543edc9abdd。所以我们可以做
movq $0xfffffffffffffff5, %rdx
movq $0x43210543edc9abdd, %rax
Run Code Online (Sandbox Code Playgroud)
如果你能让gas帮你算算那就太好了。它确实支持任意精度常量(“bignums”),但不幸的是不允许您在立即数中使用它们。正如 Jester 发现的那样(根据下面的评论),它也不能对它们进行任何算术运算。
但是,它确实支持使用指令将 128 位整数数据组装到内存中.octa。所以你可以做
.section .rodata
number:
.octa -198077031546722079779
# ...
movq number(%rip), %rax # x86 is little endian, least significant qword is at lower address
movq (number+8)(%rip), %rdx
# ...
Run Code Online (Sandbox Code Playgroud)
请注意,我们使用的是 RIP 相对寻址。如果您处于不合适的情况,那么就这样做movq number, %rax ; movq number+8, %rdx。
如果您在运行时接收数字作为输入,那么您需要实现一个十进制到二进制的转换例程(如strtol),但它使用 128 位算术。因此,加法需要一add/adc对,乘法需要几个“普通”风格的乘法指令,等等。