Assembly 大于12英寸数的阶乘(ASSEMLBY MASM)

Assembly 大于12英寸数的阶乘(ASSEMLBY MASM),assembly,masm,Assembly,Masm,我想在masm中编制一个程序,以查找1到20之间任何数字的阶乘,但我的程序对于1到12之间的数字运行良好,但不能更大。我的女士告诉我,因为您使用的eax寄存器不能保存大于32位的整数值,因此它将存储edx中的高位和eax中的低位。 这是我的密码: .model small .stack 100h .386 .data .code main proc mov eax, 13 ;user input, for 12 fac= 479001600, for 13 inc

我想在masm中编制一个程序,以查找1到20之间任何数字的阶乘,但我的程序对于1到12之间的数字运行良好,但不能更大。我的女士告诉我,因为您使用的eax寄存器不能保存大于32位的整数值,因此它将存储edx中的高位和eax中的低位。 这是我的密码:

.model small
.stack 100h
.386
.data
.code

main proc

mov eax, 13               ;user input, for 12 fac= 479001600, for 13 incorrect
mov ecx,eax
sub eax,eax
mov eax,1

loop1:
mul ecx
loop loop1

call outdec; it will print whatever in eax

main endp

;--------------------------------------------------------------

outdec proc   ;  Start of my outdec proc working accurately.
push eax
push ebx
push ecx
push edx

cmp eax,0
jge end_if

push eax
mov ah,2
mov dl,'-'
int 21h
pop ax
neg ax
end_if:

mov ebx,10
mov cx,0
rep_loop:
mov dx,0
div ebx
push edx
inc cx
cmp eax,0
jne rep_loop

mov ah,2
prent_loop:
pop edx
add dl,30h
int 21h
loop prent_loop

pop edx
pop ecx
pop ebx
pop eax
ret 
outdec endp

end main
;---------------------------------------------------------------
根据夫人的建议,我修改了我的代码,但仍然不能得到任何东西 这是我修改过的代码,在
outdec proc
中没有发生任何更改

main proc

mov eax, 13               ;user input, for 12 fac= 479001600, for 13 incorrect
mov ecx,eax
sub eax,eax
mov eax,1

loop1:
mul ecx
loop loop1

push edx    ; storing numbers of edx in stack
call outdec ; it will print whatever in eax
pop eax     ; supplanting values from stack to eax

call outdec ; again calling outdec
main endp

但是它除了在最后打印0之外什么也不做。

对于循环的每个迭代,您没有跟踪
mul
结果的高dword。由于您是“向后”乘以(从13开始,一直到1),当您达到
n==2
时,您将得到一个超过32位的乘积。此时,
eax
变为1932053504,
edx
变为1。但是你不需要将1保存在任何地方,然后你执行循环的最后一次迭代,在这里你将计算1932053504*1,这将给你
eax==1932053504
edx==0

另一个问题是,您将64位结果打印为两个独立的32位数字。如果以基数2或基数16打印它们(尽管在这种情况下,您应该先打印
edx
),那就可以了,但对于基数10,您将无法获得正确的输出。打印结果时,需要将其视为单个64位值

下面是一个工作实现的示例,以及一些解释更改的注释:

mov ecx, 13       ; n
mov eax,1
xor esi,esi       ; will be used to hold the high dword of the 64-bit product

loop1:
mul ecx           ; multiply the low dword by ecx
xchg esi,eax      ; swap eax and esi temporarily
mov ebx,edx       ; save the high dword of eax*ecx
mul ecx           ; multiply the high dword by ecx
add eax,ebx       ; and add the carry from the low-order multiplication
xchg esi,eax      ; swap eax and esi back
loop loop1

call outdec64     ; it will print whatever is in esi:eax

mov ax,0x4c00
int 0x21


;--------------------------------------------------------------

outdec64:
push eax
push ebx
push ecx
push edx

mov ebx,10
mov cx,0
rep_loop:
xor edx,edx    ; clear edx prior to the high-order division
xchg esi,eax
div ebx        ; divide the high dword of our input by 10, the remainder will carry over to the low-order division
xchg esi,eax
div ebx        ; divide the low dword of our input by 10
push edx       ; and save the remainder for printing
inc cx
cmp eax,0
jne rep_loop

mov ah,2
prent_loop:
pop edx
add dl,30h
int 21h
loop prent_loop

pop edx
pop ecx
pop ebx
pop eax
ret 

您没有跟踪循环每次迭代的
mul
结果的高dword。由于您是“向后”乘以(从13开始,一直到1),当您达到
n==2
时,您将得到一个超过32位的乘积。此时,
eax
变为1932053504,
edx
变为1。但是你不需要将1保存在任何地方,然后你执行循环的最后一次迭代,在这里你将计算1932053504*1,这将给你
eax==1932053504
edx==0

另一个问题是,您将64位结果打印为两个独立的32位数字。如果以基数2或基数16打印它们(尽管在这种情况下,您应该先打印
edx
),那就可以了,但对于基数10,您将无法获得正确的输出。打印结果时,需要将其视为单个64位值

下面是一个工作实现的示例,以及一些解释更改的注释:

mov ecx, 13       ; n
mov eax,1
xor esi,esi       ; will be used to hold the high dword of the 64-bit product

loop1:
mul ecx           ; multiply the low dword by ecx
xchg esi,eax      ; swap eax and esi temporarily
mov ebx,edx       ; save the high dword of eax*ecx
mul ecx           ; multiply the high dword by ecx
add eax,ebx       ; and add the carry from the low-order multiplication
xchg esi,eax      ; swap eax and esi back
loop loop1

call outdec64     ; it will print whatever is in esi:eax

mov ax,0x4c00
int 0x21


;--------------------------------------------------------------

outdec64:
push eax
push ebx
push ecx
push edx

mov ebx,10
mov cx,0
rep_loop:
xor edx,edx    ; clear edx prior to the high-order division
xchg esi,eax
div ebx        ; divide the high dword of our input by 10, the remainder will carry over to the low-order division
xchg esi,eax
div ebx        ; divide the low dword of our input by 10
push edx       ; and save the remainder for printing
inc cx
cmp eax,0
jne rep_loop

mov ah,2
prent_loop:
pop edx
add dl,30h
int 21h
loop prent_loop

pop edx
pop ecx
pop ebx
pop eax
ret 

您没有跟踪循环每次迭代的
mul
结果的高dword。由于您是“向后”乘以(从13开始,一直到1),当您达到
n==2
时,您将得到一个超过32位的乘积。此时,
eax
变为1932053504,
edx
变为1。但是你不需要将1保存在任何地方,然后你执行循环的最后一次迭代,在这里你将计算1932053504*1,这将给你
eax==1932053504
edx==0

另一个问题是,您将64位结果打印为两个独立的32位数字。如果以基数2或基数16打印它们(尽管在这种情况下,您应该先打印
edx
),那就可以了,但对于基数10,您将无法获得正确的输出。打印结果时,需要将其视为单个64位值

下面是一个工作实现的示例,以及一些解释更改的注释:

mov ecx, 13       ; n
mov eax,1
xor esi,esi       ; will be used to hold the high dword of the 64-bit product

loop1:
mul ecx           ; multiply the low dword by ecx
xchg esi,eax      ; swap eax and esi temporarily
mov ebx,edx       ; save the high dword of eax*ecx
mul ecx           ; multiply the high dword by ecx
add eax,ebx       ; and add the carry from the low-order multiplication
xchg esi,eax      ; swap eax and esi back
loop loop1

call outdec64     ; it will print whatever is in esi:eax

mov ax,0x4c00
int 0x21


;--------------------------------------------------------------

outdec64:
push eax
push ebx
push ecx
push edx

mov ebx,10
mov cx,0
rep_loop:
xor edx,edx    ; clear edx prior to the high-order division
xchg esi,eax
div ebx        ; divide the high dword of our input by 10, the remainder will carry over to the low-order division
xchg esi,eax
div ebx        ; divide the low dword of our input by 10
push edx       ; and save the remainder for printing
inc cx
cmp eax,0
jne rep_loop

mov ah,2
prent_loop:
pop edx
add dl,30h
int 21h
loop prent_loop

pop edx
pop ecx
pop ebx
pop eax
ret 

您没有跟踪循环每次迭代的
mul
结果的高dword。由于您是“向后”乘以(从13开始,一直到1),当您达到
n==2
时,您将得到一个超过32位的乘积。此时,
eax
变为1932053504,
edx
变为1。但是你不需要将1保存在任何地方,然后你执行循环的最后一次迭代,在这里你将计算1932053504*1,这将给你
eax==1932053504
edx==0

另一个问题是,您将64位结果打印为两个独立的32位数字。如果以基数2或基数16打印它们(尽管在这种情况下,您应该先打印
edx
),那就可以了,但对于基数10,您将无法获得正确的输出。打印结果时,需要将其视为单个64位值

下面是一个工作实现的示例,以及一些解释更改的注释:

mov ecx, 13       ; n
mov eax,1
xor esi,esi       ; will be used to hold the high dword of the 64-bit product

loop1:
mul ecx           ; multiply the low dword by ecx
xchg esi,eax      ; swap eax and esi temporarily
mov ebx,edx       ; save the high dword of eax*ecx
mul ecx           ; multiply the high dword by ecx
add eax,ebx       ; and add the carry from the low-order multiplication
xchg esi,eax      ; swap eax and esi back
loop loop1

call outdec64     ; it will print whatever is in esi:eax

mov ax,0x4c00
int 0x21


;--------------------------------------------------------------

outdec64:
push eax
push ebx
push ecx
push edx

mov ebx,10
mov cx,0
rep_loop:
xor edx,edx    ; clear edx prior to the high-order division
xchg esi,eax
div ebx        ; divide the high dword of our input by 10, the remainder will carry over to the low-order division
xchg esi,eax
div ebx        ; divide the low dword of our input by 10
push edx       ; and save the remainder for printing
inc cx
cmp eax,0
jne rep_loop

mov ah,2
prent_loop:
pop edx
add dl,30h
int 21h
loop prent_loop

pop edx
pop ecx
pop ebx
pop eax
ret