程序集 IA-32:如何将 64 位有符号数除以奇数(存储在 2 个寄存器中)
Assembly IA-32: How to divide 64-bit signed number by odd number (stored in 2 registers)
在 IA-32 架构上,我如何将 signed 数字除以 3(例如)存储在 2 个寄存器中的值, edx:eax(64 位 值)。我想将整个值(64 位)除以 3,而不仅仅是 32 位,并将其存储在 2 个寄存器中。
我假设这只能使用 shifts 操作来完成,因为 imul
仅适用于乘以 32 位数字。但只找到除以 2^n
个数字的解决方案。
我怎样才能做到这一点?
您可以将任何长度的数字除以 32 位数字并进行连续除法,使用先前除法的余数作为下一次除法的被除数的最高有效 32 位,类似于长手除法
请注意,我需要修复此代码以处理负除数,但它应该适用于正除数和带符号的股息。
请注意此代码向负无穷大舍入:-10/3:商 = -4,余数 = +2。为了处理负除数,代码可以同时对除数和被除数取反,然后对余数取反。
mov ecx,000000003h ;ecx = signed dvsr (must be positive)
mov edi,0fedcba98h ;edi:esi = signed dvnd
mov esi,076543210h
;; inputs
mov eax,edi ;eax = upper 32 bits dvnd
cdq ; sign-extend that into EDX:EAX
idiv ecx
test edx,edx ;br if sign rmdr == sign dvsr
jns short div0
dec eax ;dec quot
add edx,ecx ;rem += dvsr
div0: mov edi,eax ;edi = upper 32 bits quot
mov eax,esi ;eax = lower 32 bits dvnd
div ecx
mov esi,eax ;esi = lower 32 bits quot
; ;edx = remainder
在 IA-32 架构上,我如何将 signed 数字除以 3(例如)存储在 2 个寄存器中的值, edx:eax(64 位 值)。我想将整个值(64 位)除以 3,而不仅仅是 32 位,并将其存储在 2 个寄存器中。
我假设这只能使用 shifts 操作来完成,因为 imul
仅适用于乘以 32 位数字。但只找到除以 2^n
个数字的解决方案。
我怎样才能做到这一点?
您可以将任何长度的数字除以 32 位数字并进行连续除法,使用先前除法的余数作为下一次除法的被除数的最高有效 32 位,类似于长手除法
请注意,我需要修复此代码以处理负除数,但它应该适用于正除数和带符号的股息。
请注意此代码向负无穷大舍入:-10/3:商 = -4,余数 = +2。为了处理负除数,代码可以同时对除数和被除数取反,然后对余数取反。
mov ecx,000000003h ;ecx = signed dvsr (must be positive)
mov edi,0fedcba98h ;edi:esi = signed dvnd
mov esi,076543210h
;; inputs
mov eax,edi ;eax = upper 32 bits dvnd
cdq ; sign-extend that into EDX:EAX
idiv ecx
test edx,edx ;br if sign rmdr == sign dvsr
jns short div0
dec eax ;dec quot
add edx,ecx ;rem += dvsr
div0: mov edi,eax ;edi = upper 32 bits quot
mov eax,esi ;eax = lower 32 bits dvnd
div ecx
mov esi,eax ;esi = lower 32 bits quot
; ;edx = remainder