1

我正在学习并在此过程中进行大量使用 QWORD(x86-32 位)的汇编程序转换。现在,我的参考资料除了将它们拆分为 32 位寄存器之外,没有任何关于使用这些值的内容。我猜他们在老边。较新的处理器具有 mmx 和 sse 指令等。我会很好地研究那些解决这个问题的说明吗?处理 QWORD 值工作的最佳方法是什么?

4

2 回答 2

1

使用 64 位整数可能容易也可能不容易;取决于您要执行的操作类型。

对于布尔算术(AND、OR、XOT、NOT),只需将其拆分即可轻松处理任何长度的整数。

对于加法和减法,很容易通过链接在一起ADC(加进位)或SBB(减法借位)指令来支持任何长度的整数。例如(128 位):

add eax,[value]
adc ebx,[value+4]
adc ecx,[value+8]
adc edx,[value+12]  ;edx:ecx:ebx:eax = 128-bit result of addition

否定只是减法(-x = 0 - x)。

对于左/右移位,很容易通过链接在一起SHLDSHRD指令来支持任何长度的整数。例如(128 位):

shld edx,ecx,12
shld ecx,ebx,12
shld ebx,eax,12
shl eax,12          ;edx:ecx:ebx:eax = 128-bit result of shift left by 12

如果移位计数太大(例如,您想左移 44 位),则需要先移动数据,然后按“原始计数 MOD 32”移位。例如:

mov edx,ecx
mov ebx,ebx
mov ebx,eax
mov eax,0          ;edx:ecx:ebx:eax = original value shifted left by 32
shld edx,ecx,12
shld ecx,ebx,12
shld ebx,eax,12
shl eax,12         ;edx:ecx:ebx:eax = original value shifted left by 44

对于乘法,CPU 支持“32 位 * 32 位 = 64 位结果”。对于任何更大的东西,您可以将任何宽度整数与任何宽度整数相乘。这就像您使用 base10(其中每个数字是 0 到 9 的值)手动乘以大数的方式,但您将使用 base4294967296(其中每个数字是 32 位整数)。例如,使用 base10 将 34 x 58 倍增,您可以:

result_digit0to1 = 4*8 = 32
result_digit1to2a = 4*5 = 20
result_digit1to2b = 3*8 = 24
result_digit2to3 = 3*5 = 15
result = result_digit0to1 + (result_digit1to2 + result_digit1to2) * 10 + result_digit2to3 * 100;
result = 32 + (20 + 24) * 10 + 15 * 100
result = 32 + 440 + 1500
result = 1972

基本上,一个数字中的每个数字乘以另一个数字中的每个数字,同时跟踪数字的位置/大小;结果是中间结果的总和。

对于“64 位 * 64 位 = 128 = 位结果”,您可以执行以下操作:

result_bits0to63 = first_bits0to31 * second_bits0to31;
result_bits32to95a = first_bits32to64 * second_bits0to31;
result_bits32to95b = first_bits0to31 * second_bits32to64;
result_bits64to128 = first_bits32to64 * second_bits32to64;
result = result_bits0to63 + ( (result_bits32to95a + result_bits32to95b) << 32) + (result_bits64to128 << 64)

但是,这只适用于无符号整数。对于有符号整数,您需要删除符号位并进行无符号乘法,然后在结果中设置符号 ( result_sign_bit = first_sign_bit XOR second_sign_bit)。

对于除法,您最终会执行“base2 长除法”。您将除数尽可能向左移动,而不会丢失最高设置位(同时跟踪“位移位”)。然后将其一次移回其原始位置,同时将其与被除的值进行比较。如果移位的除数小于被除的值,则从被除的值中减去移位的除数,并在结果中设置相应的位。除数回到原来的位置后,被除的值就变成了余数。

与乘法一样,除法仅适用于无符号整数,您需要事先删除符号位,然后进行无符号除法,然后设置符号(在结果和余数中)。

如果你明白这一切;那么您将能够(例如)使用 64 位 CPU 进行 512 位数学运算,或使用 16 位 CPU 进行 65536 位数学运算,或在任何 CPU 上进行“任何宽度”数学运算。

于 2012-10-18T02:53:46.937 回答
0

最好的方法是使用与 QWORD 一起使用的指令,除非课程明确禁止这样做。然后,正如您所说,您将不得不使用 32 位寄存器来完成这项工作。您可以编写一些子程序来使用 QWORD 执行基本逻辑指令。

于 2012-10-17T23:08:36.933 回答