gpt4 book ai didi

assembly - 汇编器64b师

转载 作者:行者123 更新时间:2023-12-01 11:49:23 25 4
gpt4 key购买 nike

我需要一些简单的方法在 x86 的汇编程序中划分 64b 无符号整数。我的号码保存在两个 32b 寄存器 EDX:EAX 中,我需要将结果放回 EDX:EAX。因子是 32b 整数。一些代码,请?

最佳答案

如果我正确解释了您的问题(特别是部分 Factor is in 32b integer ),您希望将 64 位被除数除以 32 位除数并得到 64 位商。

如果这种解释是正确的,那么在 32 位代码中实际上很容易做到。

这个想法是您将除数的两个“一半”除以除数,然后将第一次除法的余数重用于第二次除法。

说明如何执行此操作的 C 代码:

#include <stdio.h>
#include <limits.h>

#define C_ASSERT(expr) extern char CAssertExtern[(expr)?1:-1]

#if UINT_MAX >= 0xFFFFFFFF
typedef unsigned int uint32;
#else
typedef unsigned long uint32;
#endif
typedef unsigned long long uint64;

typedef unsigned long ulong;

// Make sure uint32=32 bits and uint64=64 bits
C_ASSERT(sizeof(uint32) * CHAR_BIT == 32);
C_ASSERT(sizeof(uint64) * CHAR_BIT == 64);

int div64by32eq64(uint64* dividend, uint32 divisor)
{
uint32 dividendHi = (uint32)(*dividend >> 32);
uint32 dividendLo = (uint32)*dividend;
uint32 quotientHi;
uint32 quotientLo;

if (divisor == 0)
return 0;

// This can be done as one 32-bit DIV, e.g. "div ecx"
quotientHi = dividendHi / divisor;
dividendHi = dividendHi % divisor;

// This can be done as another 32-bit DIV, e.g. "div ecx"
quotientLo = (uint32)((((uint64)dividendHi << 32) + dividendLo) / divisor);

*dividend = ((uint64)quotientHi << 32) + quotientLo;

return 1;
}

int main(void)
{
static const struct
{
uint64 dividend;
uint32 divisor;
} testData[] =
{
{ 1 , 0 },
{ 0xFFFFFFFFFFFFFFFFULL, 1 },
{ 0xFFFFFFFFFFFFFFFFULL, 2 },
{ 0xFFFFFFFF00000000ULL, 0xFFFFFFFFUL },
{ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFUL },
};
int i;

for (i = 0; i < sizeof(testData)/sizeof(testData[0]); i++)
{
uint64 dividend = testData[i].dividend;
uint32 divisor = testData[i].divisor;

printf("0x%016llX / 0x%08lX = ", dividend, (ulong)divisor);

if (div64by32eq64(&dividend, divisor))
printf("0x%016llX\n", dividend);
else
printf("division by 0 error\n");
}

return 0;
}

输出( ideone ):
0x0000000000000001 / 0x00000000 = division by 0 error
0xFFFFFFFFFFFFFFFF / 0x00000001 = 0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF / 0x00000002 = 0x7FFFFFFFFFFFFFFF
0xFFFFFFFF00000000 / 0xFFFFFFFF = 0x0000000100000000
0xFFFFFFFFFFFFFFFF / 0xFFFFFFFF = 0x0000000100000001

现在汇编中的等效除法代码(NASM 语法)不检查除以 0:
; 64-bit dividend
mov edx, 0xFFFFFFFF
mov eax, 0xFFFFFFFF

; 32-bit divisor
mov ecx, 0xFFFFFFFF

push eax
mov eax, edx
xor edx, edx
div ecx ; get high 32 bits of quotient
xchg eax, [esp] ; store them on stack, get low 32 bits of dividend
div ecx ; get low 32 bits of quotient
pop edx ; 64-bit quotient in edx:eax now
; edx:eax should now be equal 0x0000000100000001

关于assembly - 汇编器64b师,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12965098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com