Loop and Constant in Assembly - loops

I just want to ask a question.
How can I display an output like this "0_1_2_3_4_5_6_7_8_9"
And I need to use a loop in the numbers, but how can I make underscore constant in every loop?
Here is my working codes.
.model small
.stack 200h
.code
main proc
mov ah, 0
mov al, 12h ; Clear screen
int 10h
mov ah,3
mov bh,0 ; get cursor
int 10h
mov ah,2
mov bh,0 ;set cursor
mov dl,12
int 10h
mov cx, 9 ; counter
Mov ah, 2
Mov dl, 48 ; display 0
top:
int 21h
add dl, 47 ; display underscore
mov ah, 2
int 21h
push dx
add dl, -46 ; return to 1
mov ah, 2
int 21h
pop dx
loop top
mov ah, 4ch
mov al,00h
int 21h
endp
end main
I always result in this, please click here
Please help me.
Thanks.

This is relative to the current digit, which will give you incorrect results for anything except when the digit is '0':
add dl, 47 ; display underscore
mov ah, 2
int 21h
You're also pushing and popping dx in the wrong places (relative to where you're changing its value).
A better approach would be:
top:
int 21h ; print digit
push dx ; save dx
mov dl,'_'
mov ah, 2
int 21h ; print underscore
pop dx ; restore dx
inc dl ; next digit
loop top

This one works fine:
; 0_9.asm
; assemble with "nasm -f bin -o 0_9.com 0_9.asm"
org 0x100 ; .com files always start 256 bytes into the segment
mov cx, 9 ; counter
mov dl, "0" ; 0
top:
push dx
push cx
mov ah, 2
int 21h
mov dl, "_" ; display underscore
mov ah, 2
int 21h
pop cx
pop dx
inc dl
loop top
mov dl, "9" ; display 9
mov ah, 2
int 21h
mov ah, 4ch ; "terminate program" sub-function
mov al,00h
int 21h

Related

I have an indexing problems

I need to write names from keyboard and then display them, one on each line. They should be displayed with an index before of them. For example if I write the names elena and maria the should be displayed as 1.elena 2.maria
I tried adding a counter variable but I have some errors when I try to run the program in DosBox. Can someone help me? Here is my clean label that is outputting the names:
lista:
mov dx, offset nume
print_names:
push dx
mov dl, 13 ; carriage return
mov ah, 02h
int 21h
mov dl, 10 ; linefeed
mov ah, 02h
int 21h
pop dx
mov dx, offset index
mov ah, 9
int 21h
inc byte ptr index
mov dx, offset nume
mov ah, 09h
int 21h
; (*)
add dx, 5 + 1
cmp dx, numePointer ; check if the current name is the last one
jb print_names
jmp bucla ; return to main loop
The addition is destroying the DX pointer for the name to be displayed!
Why did you put the additional code between proc endp?
punct db '.' ,10, '$' does not need the 10. Should be punct db '.$' or even better, combine it with index like in index db '?.$'.
And still better, combine the newline with it too:
lista:
mov dx, offset nume
print_names:
push dx ; (1)
mov dx, offset numeIndex
mov ah, 09h
int 21h
inc byte ptr [numeIndex + 2] ; "1" -> "2" -> "3" ...
pop dx ; (1)
mov ah, 09h
int 21h
add dx, 5 + 1
cmp dx, numePointer ; check if the current name is the last one
jb print_names
jmp bucla ; return to main loop
...
numeIndex db 13, 10, 49, 46, 36

Subtraction of Two Arrays and Stores Result in 3rd array and display the result on screen in Assembly language 8086

I have already written the code to add TWO arrays and Store the result in 3rd array. But the problem occurs while handling the NEGATIVE SIGN Numbers to display with (-) sign. Follow are the code listed below while subtracting the 6th element of array1 with array 2, result is GARBAGE value Need assistance immediately. After running executing's the code, all signed values are not displaying correctly.
org 100h
Array1 db 1,3,2,2,2,2,2,2,2,2
Array2 db 4,5,6,7,8,9,0,1,2,3
Array3 db 10 dup (?)
lea dx, msg1
mov ah, 9
int 21h
mov cx, 10
mov bx, 0
L1001:
mov al, Array1 [bx]
; Extend (unsigned) AL to AX (to print)
mov ah, 0
call printd
mov ah, 2
mov dl, 09 ;TAB Character
int 21h
inc bx
loop L1001 ;End Loop1
mov ah,2
mov dl,10
int 21h
mov dl,13
int 21h
; print msg2
lea dx, msg2
mov ah, 9
int 21h
; Use loop to print values of Array2
mov cx, 10
mov bx, 0
L1002:
mov al, Array2 [bx]
; Extend (unsigned) AL to AX (to print)
mov ah, 0
call printd
mov ah, 2
mov dl, 09 ;TAB Character
int 21h
inc bx
loop L1002 End Loop2
mov ah,2
mov dl,10
int 21h
mov dl,13
int 21h
; print msg3
lea dx, msg3
mov ah, 9
int 21h
mov cx,10
mov bx, 0
L1003: ; Main Addition
mov al, Array1 [bx]
sub al, Array2 [bx]
mov Array3 [bx], al
; Extend (unsigned) AL to AX (to print)
mov ah, 0
call printd
mov ah, 2
mov dl, 09 ;TAB Character
int 21h
inc bx
loop L1003 ; End of lOOP3
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
printd proc
; preserve used registers
push ax
push bx
push cx
push dx
; if negative value, print - and call again with -value
cmp ax, 0
jge L1
mov bx, ax
; print -
mov dl, '-'
mov ah, 2
int 21h
; call with -AX
mov ax, bx
neg ax
call printd
jmp L3
L1:
; divide ax by 10
; ( (dx=0:)ax / cx(= 10) )
mov dx, 0
mov cx, 10
div cx
; if quotient is zero, then print remainder
cmp ax, 0
jne L2
add dl, '0'
mov ah, 2
int 21h
jmp L3
L2:
; if the quotient is not zero, we first call
; printd again for the quotient, and then we
; print the remainder.
; call printd for quotient:
call printd
; print the remainder
add dl, '0'
mov ah, 2
int 21h
L3:
; recover used registers
pop dx
pop cx
pop bx
pop ax
ret
printd endp
printud proc ;Print Undecimal Numbers
push ax
push bx
push cx
push dx
mov dx, 0
mov cx, 10
div cx
cmp ax, 0
jne L4
add dl, '0'
mov ah, 2
int 21h
jmp L5
L4:
call printud
add dl, '0'
mov ah, 2
int 21h
L5:
pop dx
pop cx
pop bx
pop ax
ret
printud endp ;
ret
msg1 db "Array 1 = $"
msg2 db "Array 2 = $"
msg3 db "Array 3 = : $"
pkey db "press any key...$"
mov al, Array1 [bx]
sub al, Array2 [bx]
mov Array3 [bx], al
; Extend (unsigned) AL to AX (to print)
mov ah, 0
call printd
You say that your program is having trouble displaying the negative numbers, but your code is never feeding any negative number to the printd routine! Whatever the signed result of the subtraction in AL may be, the mov ah, 0 that follows will produce a positive number in AX and it is AX that printd processes...
You should replace mov ah, 0 by cbw.
But, what is terribly wrong is the placement of the 3 arrays. They can't be at the top of the program like that. The cpu is executing their bytes (data) as if it were instructions (code)!
Move those 3 lines towards the bottom of the source.
It surprised me to see these recursive solutions to display a decimal number. I believe they are correct with one exception though! If you feed printd the negative number -32768 then the program will fall into an infinite loop. This happens because the negation of that particular value is again -32768.
You might want to investigate Displaying numbers with DOS for info about the iterative solution that is surely faster (and could be improved further by outputting the digits all at once).

Using loop in assembly language using DOSBOX

Hello I need to show the output like this
9_8_7_6_5_4_3_2_1_0
But I am having a difficulty to store the "underscore" temporarily and as I notice registers like DH, CH, BH, BL can't be use to output using int int 21H. Here is my code
.model small
.stack
.data
.code
begin:
mov ah, 2
mov cx, 10
mov dl, 39h
int 21h
back: mov dl, 5fh
int 21h
sub dl, 39
int 21h
loop back
mov ah,4ch
int 21h
end begin
You can use another register to store the counter (9..0), for example, bl :
.model small
.stack
.data
.code
begin:
mov ah, 2
mov cx, 10
mov bl, '9' ;◄■■ COUNTER 9..0.
back:
mov dl, bl ;◄■■ MOVE COUNTER INTO DL.
int 21h ;◄■■ DISPLAY COUNTER.
dec bl ;◄■■ COUNTER-1.
mov dl, 5fh ;◄■■ MOVE UNDERSCORE INTO DL.
int 21h ;◄■■ DISPLAY UNDERSCORE.
loop back
mov ah,4ch
int 21h
end begin

Assembly loop char

I want to use the LOOP instruction to print this string in assembly :
abcccbcccabcccbccc
We have ab, ccc, b and then backup to ab and then ccc.
I hope I will find some solutions with your help.
I am using emu to compile the source !
.model small
.stack 200h
.code
main PROC
mov ah, 0
mov al, 12h ; Clear screen
int 10h
mov ah, 3
mov bh, 0 ; get cursor
int 10h
mov ah, 2
mov bh, 0 ;set cursor
mov dl,12
int 10h
mov cx, 5 ; counter
mov dl, 65 ; ASCII of 'A'
t1:
mov ah, 2h
int 21h
add dl, 32 ; 97 - 65 - convert to LC
mov ah, 2h
int 21h
sub dl,31 ;remove the 32 added, but increment
push dx ;save DX on stack
mov dl, 32 ;space character
mov ah, 2h
int 21h
pop dx ;return DX from stack
loop t1
mov ah, 4Ch ;exit DOS program
mov al, 00h ;return code = 0
int 21h
ENDP
END main
Next 2 small programs are 2 possible solutions to your problem :
SOLUTION #1
.stack 100h
.data
txt db 'abcccbccc$' ;STRING TO DISPLAY.
.code
mov ax, #data ;INITIALIZA DATA SEGMENT.
mov ds, ax
mov cx, 3 ;DISPLAY STRING 3 TIMES.
t1:
mov ah, 9
mov dx, offset txt
int 21h
loop t1
mov ax, 4c00h ;TERMINATE PROGRAM.
int 21h
SOLUTION #2
.stack 100h
.data
s1 db 'ab$' ;STRING TO DISPLAY.
s2 db 'ccc$' ;STRING TO DISPLAY.
s3 db 'b$' ;STRING TO DISPLAY.
.code
mov ax, #data ;INITIALIZA DATA SEGMENT.
mov ds, ax
mov cx, 12 ;DISPLAY THE 4 STRING 3 TIMES.
mov bl, 1 ;1 = DISPLAY STRING S1.
;2 = DISPLAY STRING S2.
;3 = DISPLAY STRING S3.
;4 = DISPLAY STRING S2.
mov ah, 9 ;NECESSARY TO DISPLAY STRINGS.
t1:
;BL TELLS WHAT TO DO.
cmp bl, 1
je string1 ;BL=1 : DISPLAY S1.
cmp bl, 2
je string2 ;BL=2 : DISPLAY S2.
cmp bl, 3
je string3 ;BL=3 : DISPLAY S3.
;string4: ;BL=4 : DISPLAY S2.
mov dx, offset s2
int 21h
jmp continue ;SKIP NEXT DISPLAYS.
string1:
mov dx, offset s1
int 21h
jmp continue ;SKIP NEXT DISPLAYS.
string2:
mov dx, offset s2
int 21h
jmp continue ;SKIP NEXT DISPLAYS.
string3:
mov dx, offset s3
int 21h
continue:
inc bl ;BL TELLS WHAT TO DO.
cmp bl, 4
jbe nextstring ;IF BL < 4
mov bl, 1 ;BL STARTS AGAIN.
nextstring:
loop t1
mov ax, 4c00h ;TERMINATE PROGRAM.
int 21h

Assembly program to print 'a' to 'z' using stack, loop cx and dx

I've got an assignment to make an assembly program which print 'a' to 'z' vertically line by line using stack, loop cx and dx.
Can anyone help me please.
This is program of printing a to z, but i dont have an idea how to use stack cx and dx in my program:
.data
l1c db 0ah,0dh,"S"
.code
main proc
mov ax #data
mov ds,ax
mov al,48
mov cx,10
d:
mov dl,al
mov ah,2
int 21h
call linechange
inc al
loop d
mov ah,4ch
int 21h
main endp
;Procedure
linechange proc
lea dx,l1c
mov ah,9
int 21h
ret
linechnage endp
end main
(this is the program which i made by my self)
I guess your teacher wanted to avoid a "clever" solution like:
.MODEL SMALL
.STACK 1000h
.DATA
smart_out db 'a',13,10,'b',13,10,'b',13,10,'c',13,10,'d',13,10,'e',13,10
db 'f',13,10,'g',13,10,'h',13,10,'i',13,10,'j',13,10,'k',13,10
db 'l',13,10,'m',13,10,'n',13,10,'o',13,10,'p',13,10,'q',13,10
db 'r',13,10,'s',13,10,'t',13,10,'u',13,10,'v',13,10,'w',13,10
db 'x',13,10,'y',13,10,'z',13,10,'$'
.CODE
main:
mov ax, #data
mov ds, ax
mov ah, 9
mov dx, OFFSET smart_out
int 21h
mov ax, 4C00h
int 21h
END main
You are supposed to output this with a LOOP (CX needed). In a loop you need to preserve at least AX and CX since you never know if a procedure like INT 21h will change it. A call to INT 21h / 9 fulfills the third condition since it needs a value in DX:
.MODEL SMALL
.STACK 1000h ; Reserve space for stack and initialize stack pointer
.DATA
l1c db 0dh, 0ah, '$' ; Dollar-sign!
.CODE
main PROC
mov ax, #data
mov ds, ax
mov al, 'a'
mov cx, 26
d:
push ax ; Store AX (AL is a part of AX)
push cx ; Store CX
mov dl, al
mov ah, 2
int 21h
mov ah, 9
mov dx, OFFSET l1c
int 21h
pop cx ; Restore CX & AX in reversed push-order
pop ax
inc al
loop d ; Loops until cx == 0
mov ah, 4ch
int 21h
main ENDP
END main

Resources