我决定学习x86 Assembly作为我的第一个严肃的编程语言。
我决定编写一个计算给定数字的阶乘的程序。
代码工作正常,直到大于12!,之后我得到不正确的结果。
我怀疑这是由于结果大于32位。正确的吗?
为了纠正这个问题,我尝试了rcl
edx寄存器。
15!应该是1307674368000但是,它返回27701857280。
.386
.model flat, stdcall
option casemap :none
includelib \masm32\lib\msvcrt.lib
sprintf proto C :vararg
includelib \masm32\lib\user32.lib
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD
includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword
.data
format db "%lld", 13, 10, 0
_title db "Result",13,10,0
.code
main PROC
LOCAL szBuf[9]:byte
xor edx,edx
rcl edx ,1
xor ebx,ebx
mov eax, 15 ; start of 15!
mov ebx,eax ; Prepares # of loop counter cycle
factoral:
dec ebx ;loop counter
jz ready ;when ebx = 0 jump to ready step
imul eax, ebx ; Multiply for intermeddiate result.
rcl edx, 1 ; Shift carry flag to edx to handle > 32 bit results.
jnz factoral ; Continue loop counter when ebx > 0
ready:
invoke sprintf, addr szBuf, offset format, eax, edx
invoke MessageBoxA, 0, addr szBuf, offset _title, 0
invoke ExitProcess, 0
main ENDP
END main
额外:使用shl eax, 1
计算中间人的第二度部分(n * 2)比使用imul
每个度数更好。
示例:5!
1)(5 * 4 = 20)
2)(20 * 3 = 60)
3)(60左移位1次= 120)
4)(120 * 1 = 120)