I have to do o program which read a number between 0 and 255 and print a half pyramid, like this:
input: 4
output:
1
1 2
1 2 3
1 2 3 4
I've managed to do it for numbers between 0 and 9, but i really can't do it for two or three digits numbers.
See the following code
.model small
.stack 100h
.data
msg db "Enter the desired value: $", 10, 13
nr db ?
.code
mov AX, @data
mov DS, AX
mov dl, 10
mov ah, 02h
int 21h
mov dl, 13
mov ah, 02h
int 21h
mov DX, OFFSET msg
mov AH, 9
int 21h
xor ax, ax
mov ah, 08h
int 21h
mov ah, 02h
mov dl, al
int 21h
sub al,30h
mov ah,10
mul ah
mov [nr],al
mov ah, 08h
int 21h
mov ah, 02h
mov dl, al
int 21h
sub al, 30h
add [nr], al
sub nr,30h
mov dl, 10
mov ah, 02h
int 21h
mov dl, 13
mov ah, 02h
int 21h
mov cx,1
mov bx,31h
mov ah, 2
mov dx, bx
int 21h
loop1:
xor ax, ax
mov al, nr
cmp ax, cx
je final
mov dl, 10
mov ah, 02h
int 21h
mov dl, 13
mov ah, 02h
int 21h
mov bx, 0
loop2:
inc bx
add bx,30h
call function
int 21h
sub bx,30h
cmp bx, cx
jne loop2
inc bx
add bx,30h
mov ah, 2
mov dx, bx
int 21h
inc cx
jmp loop1
function:
MOV BX,10
ASC2:
mov dx,0 ; clear dx prior to dividing dx:ax by bx
DIV BX ;DIV AX/10
ADD DX,48 ;ADD 48 TO REMAINDER TO GET ASCII CHARACTER OF NUMBER
dec si ; store characters in reverse order
mov [si],dl
CMP AX,0
JZ EXTT ;IF AX=0, END OF THE PROCEDURE
JMP ASC2 ;ELSE REPEAT
EXTT:
mov ah,9 ; print string
mov dx,si
int 21h
final:
mov AH,4Ch ; Function to exit
mov AL,00 ; Return 00
int 21h
end
(each paragraph below it's one bug/problem, to be addressed ... maybe you should start from scratch and try to write something more elegant, because this is a bit "messy")
What is sub nr,30h
(after add [nr], al
)? Can you explain, what it does? Try to imagine, what value is in the [nr]
and what will that sub do to it. You have to decide, whether you work with numerical values, or ASCII characters, don't mix the two together mindlessly.
Move those "new line" sequences into separate procedure, so you can do call newline
instead of those 6 lines, it will make easier to read the source, plus you can wrap them around with push/pop
to preserve register values.
Why ah=8, int 21h
input char, when you then output it? You can use ah=1
"with echo" input then.
add bx,30h
call function
^^ again, if bx
is numerical value like 15
, adding '0'
to it before conversion to ASCII doesn't make sense. It will turn the 15
into 63
, and display "63"
(if your " function
" is correct - it is not).
int 21h
after call function
does WHAT?
The function:
will not return.
The function:
works like argument was in ax
, but the main code is calling it with bx
I guess... nevertheless, bx
content will be destroyed, while main code doesn't expect that.
etc...etc... too much of it. Just delete it, and start over. Stop adding random instructions to code, first make sure you have high-level overview and clear idea, what you want to do with which value and why, then write only instructions doing that. Verify in debugger often, that 2-6 new lines do what you EXPECT (because they will very likely not). "Adding just bunch of instructions and modifying them a bit, until it will work" approach may work in some high level language, but in Assembly there's million of possibilities with only 20 instruction long code, so it may take years. Rather focus to KNOW what you expect, so you can then easily compare state of debugger with your expectations, and find any discrepancy.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.