Reputation:
Following is my code :
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
I am aware that the program isn't correct. Here are the questions I have about this (I am trying to learn procedures) :
endp
or [name] endp
(multiple books are giving me multiple answers)imul
returns 18 in AL
? How?ret
statement, the program jumps to the previous statement, not the statement after procedure endAnd help is appreciated!
Upvotes: 1
Views: 11956
Reputation: 1
;The following program is used to find the factorial of a number in 8086 assembly include 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
Upvotes: 0
Reputation: 20631
To end a procedure, do we write directly endp or [name] endp
Try it and see... I believe either will work. Including the name improves clarity.
When it reaches the multiplication of 4*6, imul returns 18 in al? how?
Because 4 times 6 is 24 (in decimal) which is 18 in hexadecimal.
After ret statement, the program jumps to the previous statement, not the statement after procedure end
ret
causes the execution to continue from the point at which the procedure was called. Since your procedure calls itself - i.e. it recurses - the ret instruction could cause it to return to the line just before the ret
instruction simply because the corresponding call
is the line before that. Probably, that (second) call
instruction should really be a jmp
instruction, to return to the start of the procedure without recursing. Then, the ret
will always return to the instruction after the original call
.
At that point, however, you have another problem. Since you have the procedure immediately after the call point, the ret
instruction will cause execution to resume at the beginning of the procedure; when it reaches ret
again your program will likely crash. The code you have written after the end of the procedure should instead be moved so that it is after the call point (i.e. it should be between the call point and the procedure).
Upvotes: 2