在 8086 汇编中查找一个数的阶乘
Finding factorial of a number in 8086 assembly
以下是我的代码:
data segment
num db 05h
fact db 02h
data ends
code segment
assume cs:code, ds:data
start: mov dx,data
mov ds,dx
mov al,01h
mov bl,num
inc bl
call prc
prc proc
imul fact
inc fact
cmp fact,bl
jz endproc
call prc
endproc: mov fact,al
ret
prc endp
mov ah,4ch
int 21h
code ends
end start
我知道程序不正确。这是我对此的疑问(我正在尝试学习程序):
- 结束一个程序,是直接写
endp
还是[name] endp
(多本书给我多个答案)
- 当达到4*6的乘法时,
imul
returns18在AL
?怎么样?
- 在
ret
语句之后,程序跳转到上一条语句,而不是程序结束后的语句
感谢帮助!
To end a procedure, do we write directly endp or [name] endp
试试看...我相信两者都可以。包括名称可以提高清晰度。
When it reaches the multiplication of 4*6, imul returns 18 in al? how?
因为 4 乘以 6 是 24(十进制),十六进制是 18。
After ret statement, the program jumps to the previous statement, not the statement after procedure end
ret
使执行从调用过程的点继续。由于您的过程调用自身 - 即它 recurses - ret 指令可能导致它 return 到 ret
指令之前的行,因为相应的 call
是之前的那一行。可能那个(第二个)call
指令实际上应该是一个 jmp
指令,到 return 到过程的开始而不递归。然后,ret
将始终 return 到原始 call
之后的指令。
然而,此时您遇到了另一个问题。由于您在调用点之后立即拥有过程,因此 ret
指令将导致在过程开始处恢复执行;当它再次达到 ret
时,您的程序可能会崩溃。您在过程结束后编写的代码应该移动到调用点之后(即它应该在调用点和过程之间)。
;下面的程序是用8086汇编求一个数的阶乘
包括 emu8086.inc
org 100h
call input
call check
call factorial
ret
input proc
lea dx,msg
mov ah,9
int 21h ;to print the string
mov ah,1
int 21h ;input from the user one character
sub al,30h ;to change the ascii into our decimal number
mov ch,al
mov ah,1
int 21h
sub al,30h
mov cl,al
print '!'
ret
input endp
check proc
cmp ch,0 ;ch-0
je fact ;if they are equal jump to the factorial
lea dx,msg2
mov ah,9
int 21h
hlt
ret
check endp
fact:
factorial proc
lea dx,msg1
mov ah,9
int 21h
mov ax,1 ;initialize
label:
cmp cx,0
je quit
mul cx ;ax=ax*cx
loop label
quit:
call print_num_uns ;to print the number found in ax register
ends
factorial endp
mov ah,4ch ;to return control to the operating system
int 21h
msg db 'Enter the number: $'
msg1 db 10,13,'The factorial is: $'
msg2 db 10,13,'The factorial is out of bound,sorry we can not help you $'
define_print_num_uns
end
以下是我的代码:
data segment
num db 05h
fact db 02h
data ends
code segment
assume cs:code, ds:data
start: mov dx,data
mov ds,dx
mov al,01h
mov bl,num
inc bl
call prc
prc proc
imul fact
inc fact
cmp fact,bl
jz endproc
call prc
endproc: mov fact,al
ret
prc endp
mov ah,4ch
int 21h
code ends
end start
我知道程序不正确。这是我对此的疑问(我正在尝试学习程序):
- 结束一个程序,是直接写
endp
还是[name] endp
(多本书给我多个答案) - 当达到4*6的乘法时,
imul
returns18在AL
?怎么样? - 在
ret
语句之后,程序跳转到上一条语句,而不是程序结束后的语句
感谢帮助!
To end a procedure, do we write directly endp or [name] endp
试试看...我相信两者都可以。包括名称可以提高清晰度。
When it reaches the multiplication of 4*6, imul returns 18 in al? how?
因为 4 乘以 6 是 24(十进制),十六进制是 18。
After ret statement, the program jumps to the previous statement, not the statement after procedure end
ret
使执行从调用过程的点继续。由于您的过程调用自身 - 即它 recurses - ret 指令可能导致它 return 到 ret
指令之前的行,因为相应的 call
是之前的那一行。可能那个(第二个)call
指令实际上应该是一个 jmp
指令,到 return 到过程的开始而不递归。然后,ret
将始终 return 到原始 call
之后的指令。
然而,此时您遇到了另一个问题。由于您在调用点之后立即拥有过程,因此 ret
指令将导致在过程开始处恢复执行;当它再次达到 ret
时,您的程序可能会崩溃。您在过程结束后编写的代码应该移动到调用点之后(即它应该在调用点和过程之间)。
;下面的程序是用8086汇编求一个数的阶乘 包括 emu8086.inc
org 100h
call input
call check
call factorial
ret
input proc
lea dx,msg
mov ah,9
int 21h ;to print the string
mov ah,1
int 21h ;input from the user one character
sub al,30h ;to change the ascii into our decimal number
mov ch,al
mov ah,1
int 21h
sub al,30h
mov cl,al
print '!'
ret
input endp
check proc
cmp ch,0 ;ch-0
je fact ;if they are equal jump to the factorial
lea dx,msg2
mov ah,9
int 21h
hlt
ret
check endp
fact:
factorial proc
lea dx,msg1
mov ah,9
int 21h
mov ax,1 ;initialize
label:
cmp cx,0
je quit
mul cx ;ax=ax*cx
loop label
quit:
call print_num_uns ;to print the number found in ax register
ends
factorial endp
mov ah,4ch ;to return control to the operating system
int 21h
msg db 'Enter the number: $'
msg1 db 10,13,'The factorial is: $'
msg2 db 10,13,'The factorial is out of bound,sorry we can not help you $'
define_print_num_uns
end