Reputation: 61
I am developing this exercise:
write the assembler program that, given a character as input, outputs a triangle of size 5 x 5 of the character itself.
I have a problem because when I go to input a character, the characters do not form a triangle, but other characters are printed.
My input:
f
My output:
Desired output:
f
ff
fff
ffff
fffff
My code:
Title PROVA
;programma per la prova dell’ambiente Turbo Assembler
DOSSEG
.MODEL SMALL
.STACK 100
.DATA
; se ci sono qui vanno dichiarate le vriabili
.CODE
MOV AX, @data ;(obbligatorie) inizializzano il DS
MOV DS, AX
MOV AX, 00
MOV BX, 00
MOV CX, 00
MOV DX, 00
mov ah,01h ;input va a mettere l'input in AL ;n
int 21h
MOV BL, AL ;n
MOV CL, BL ;n
MOV CH, 0H
ciclo:
CMP CH, 5H
JE fine
inc CH
MOV DL, BL
mov ah, 02h ;stampa il contenuto di dl
int 21h
mov DL, 10D
int 21h
mov DL, 13D
int 21h
;BL
ADD BL, CL
JMP ciclo
fine:
MOV AL, 00H ;(obbligatorie) ritornano il controllo al sistema operativo
MOV AH, 4CH
INT 21H
END
Upvotes: 1
Views: 1480
Reputation: 39191
ADD BL, CL JMP ciclo
You seem to expect that this addition will double the number of characters. That is not the case! With BL and CL both holding your inputted "f" character, this instruction will just double the ASCII code for that particular character. And the DOS.PrintCharacter function 02h will only ever print a single character, so you need to repeat that operation in a loop.
MOV AX, @data ;(obbligatorie) inizializzano il DS MOV DS, AX
If your program does not use items from the .DATA sections then setting up the DS segment register can be safely omitted.
MOV AX, 00 MOV BX, 00 MOV CX, 00 MOV DX, 00
This code is correct, but it is almost never needed to zero all your registers at program start. This program being a perfect example...
MOV AL, 00H ;(obbligatorie) ritornano il controllo al sistema operativo MOV AH, 4CH INT 21H
Again, this code is correct, but it is definitely not better to load AL and AH separately, when you can write mov ax, 4C00h
.
This is your improved program:
Title PROVA
;programma per la prova dell’ambiente Turbo Assembler
DOSSEG
.MODEL SMALL
.STACK 100
.DATA
; se ci sono qui vanno dichiarate le vriabili
.CODE
mov ah, 01h ; DOS.GetKeyboardCharacter
int 21h ; -> AL
mov bl, al
mov ah, 02h ; DOS.PrintCharacter
mov bp, 1 ; BP is number of characters on current line
OuterLoop:
mov cx, bp ; Setup count in CX for the inner loop that follows
mov dl, bl ; BL is the inputted character
InnerLoop:
int 21h ; -> AL == DL (BL)
loop InnerLoop
mov dl, 13 ; Carriage return
int 21h ; -> AL == DL (13)
mov dl, 10 ; Linefeed
int 21h ; -> AL == DL (10)
inc bp
cmp bp, 6
jb OuterLoop
mov ax, 4C00h ; DOS.TerminateWithReturncode
int 21h
END
Below is my version that builds the entire output in a buffer memory and then prints it all at once with a single invokation of the DOS.PrintString function 09h.
It is perhaps not the most obvious way to solve this particular, extremely simple task, but at least:
Title PROVA
;programma per la prova dell’ambiente Turbo Assembler
DOSSEG
.MODEL SMALL
.STACK 100
.DATA
Buffer db 100 dup (0)
.CODE
mov ax, @data
mov ds, ax
mov ah, 01h ; DOS.GetKeyboardCharacter
int 21h ; -> AL
mov dx, OFFSET Buffer
mov di, dx
xor cx, cx ; CX is number of characters on current line
OuterLoop:
inc cx ; -> CX=[1,5]
mov bx, cx
mov word ptr [di+bx], 0A0Dh ; Carriage return and linefeed together
InnerLoop:
dec bx ; (*)
mov [di+bx], al ; AL is the inputted character
jnz InnerLoop ; (*) Acts on the flags defined by `DEC BX`
add di, cx
add di, 2
cmp cx, 5
jb OuterLoop
mov byte ptr [di], "$"
mov ah, 09h ; DOS.PrintString
int 21h ; -> AL == "$"
mov ax, 4C00h ; DOS.TerminateWithReturncode
int 21h
END
Upvotes: 1
Reputation: 460
I solved in this way
org 100h
MOV AH, 2
MOV BX, 0
row:
INC BX
MOV CX,BX
col:
MOV DL, 102
int 21h
loop col
MOV DL ,010
INT 21h
MOV DL, 13
INT 21h
CMP BL, 5
JE break
JMP row
break:
ret
ret
Upvotes: 0
Reputation: 502
As vitsoft pointed out, the char changed because you add CL
to BL
.
To make a triangle you need to use another loop, as Michael said.
Below is the part to change:
MOV AH, 01h ; input va a mettere l'input in AL ;n
INT 21H
MOV BL, AL ; n
MOV CH, 0H
ciclo:
CMP CH, 5H
JE fine
INC CH
MOV DL, 10D
INT 21H
MOV DL, 13D
INT 21H
MOV CL, CH
MOV AH, 02H ; stampa il contenuto di dl
MOV DL, BL
innerLoop:
INT 21H
DEC CL
JNE innerLoop
JMP ciclo
fine:
Upvotes: 1