This question already has answers here:
why does the interruption int 21h ignore all strings after writing a string filled durring the execution of the program?
(2 answers)
Weird garbage in output
(1 answer)
Assembly, printing ascii number
(4 answers)
Displaying Time in Assembly
(3 answers)
How to index arrays properly in x86 assembly
(4 answers)
Closed 1 year ago.
I am working on an assembly assignment for school. The objective is to take two numbers from user input, add them and then output the result on screen. However, the array, output, that holds the results of the operations to be outputted will not print out to the screen whatsoever. I am really not sure exactly what is wrong here. My print_output function works as a whole since it will print out other strings and arrays if I tell it to do so. Due to this I think I might have an indexing issue with accessing the input array for the data need for the operations that causes issues later or maybe something with my arithmetic but that is really my only hunch. Thanks for any help with this. Note: In response to Michael's comment I edited the program back for the array to terminate in a $ but the problem was still occuring past that.
.model small
.stack 64
.data
Prompt DB 'Enter a number between 10 and 49 number: ', '$'
Prompt2 DB 'Enter another number between 10 and 49 number: ', '$'
StrPar LABEL BYTE
StrPar2 LABEL BYTE
Actual_Len DB 4
Chars DB 4 DUP('$')
output DB 4 DUP('$')
.code
MAIN proc FAR
mov AX,#data
mov DS,AX
call Clear
call Set_Cursor
call Request_Input
call Get_Input
call Add_Input
call Clear
call Set_Cursor
call Request_Input2
call Get_Input
call Clear
call Set_Cursor
call Add_Input2
call Prep_Output
call Print_Output
mov AX,4C00h
int 21h
MAIN endp
;________________________
Clear proc NEAR
mov AX, 06H
mov AL, 00H
mov BH, 71H
mov CX, 0000H
mov DX, 184FH
int 10H
ret
Clear endp
;__________________________
Set_Cursor proc NEAR
mov AH, 02H
mov BH, 0
mov DH, 10
mov DL, 5
int 10H
ret
Set_Cursor endp
;___________________________
Request_Input proc NEAR
mov AH, 09H
lea DX,Prompt
int 21H
ret
Request_Input endp
;___________________________
Request_Input2 proc NEAR
mov AH, 09H
lea DX,Prompt2
int 21H
ret
Request_Input2 endp
;__________________________
Get_Input proc NEAR
mov AH, 0AH
lea DX, StrPar
int 21H
mov BH,00
mov BL,Actual_Len
mov Chars[BX],'$'
ret
Get_Input endp
;__________________________
;_________________________
Add_Input proc NEAR
mov AH, 00
mov DX, 00
mov BX,1
mov DL, Chars[BX]
sub DL,48
mov AX,10
mul DX
mov DX,AX
mov BX,2
mov CX,00
mov CL, Chars[BX]
sub CX,48
add DX,CX
ret
Add_Input endp
;______________________
Add_Input2 proc Near
mov AX,00
mov BX,1
mov CL, Chars[BX]
sub CX, 48
mov AX,10
mul CX
mov CX,AX
mov BX,2
mov BL, Chars[BX]
sub BL,48
mov BH,00
add CX,BX
ret
Add_Input2 endp
;______________________
Prep_Output proc NEAR
mov AX,00
add DX,CX
mov AX,DX
mov BX,10
div BL
add AL,48
add AH,48
mov BX, 1
mov output[BX],AL
mov BX, 2
mov output[BX],AH
ret
Prep_Output endp
;________________________
Print_Output proc NEAR
mov AH, 09H
lea DX, output
int 21H
ret
Print_Output endp
end MAIN
Related
So, basically I just want to display the first data from array which is userbalanceIndex1 from userbalanceIndex.
But I get an error which is
DEMO.ASM(29): Out of memory
29 line: mov bl,(userbalanceIndex +1)
Here is my code:
.model small
.stack 100H
.data
userbalanceIndex db usrbalance1, usrbalance2, usrbalance3, usrbalance4
usrbalance1 Db 1
usrbalance2 Db 9
usrbalance3 Db 6
usrbalance4 Db 0
.code
OUTPUT MACRO DIGIT
MOV AH, 02H
MOV DL, DIGIT
INT 21H
ENDM
main proc
MOV AX,#DATA
MOV DS,AX
mov al, userbalanceIndex
mov cx, 0
a:
inc userbalanceIndex
mov bl, (userbalanceIndex + 1)
loop a
OUTPUT bl
mov ah, 4ch
int 21h
main endp
end main
I want to print this array but also highlight specific characters from said array. This is my code:
include 'emu8086.inc'
.data
animales1 db 'BUBRPQYFODFZXIQ'
db 'MSVDJVQDTLOEATF'
db 'RCZPIFYGAZLPMFN'
db 'LVWKFFBKDXHFIUW'
db 'AOSEFQEMOOTGQUR'
db 'ELLWTGNJJKAJISJ'
db 'OVCOXLUEQTSDDSP'
db 'UEAEMTNYOLVYMGI'
db 'ORREPOMJZGYPHAI'
db 'IFTLCBJFVOYHLUB'
db 'WTOWZQFRAXQRLMR'
db 'KGNYIIHHHKFUKIJ'
db 'XMLSACGMVXEYSIT'
db 'TSOESQVSEQRFNPU'
db 'ODDQMDFWRGETDLY'
lenguajes2 db 'SLKFMBCULKVYUIM'
db 'TWCDQFYIVIKUXKB'
db 'GNIWEQBOSYEMDTJ'
db 'WDHFZZPUIEDERYQ'
db 'KMTGTKAKROMUSUV'
db 'BELBLLTUVJQHCRW'
db 'UPLUBYJKNUXORLF'
db 'SGMAOOEENBOGIWR'
db 'JVSTLPTEGPPNPJW'
db 'YINCASSEMBLYTTU'
db 'CHWTIOIWORDZDRV'
db 'BRZCNRAVRWAMUNU'
db 'KOMCOUKNGQEPQVS'
db 'XXRXJUJUBEXVGGA'
db 'MNKJQKZAACVCLDW'
char db 'a'
flag db 0
;Pez= 12,27,42
;Ave= 76,92,108
indx db 5,11,26,41,45 dup (' ')
.stack
.code
.start up
mov ax,0000h
mov bx,0000h
mov cx,0000h
mov dx,0000h
lea si, animales1
;call valueInArray
call printArrays
printArrays proc
mov bx,0000h
printArray:
mov dx,0000h
mov ah, 02h
mov dl,byte ptr[si+bx]
call valueinArray
cmp flag,1
jz printSpecial
int 21h
mov dl, 20h
int 21h
add bx, 1
add cl, 1
cmp cl,15
jz nextRow
jnz printArray
nextRow:
call nwLine
add ch,1
mov cl, 00h
cmp ch,15
jz finproc
jnz printArray
printSpecial:
lea di,char
mov byte ptr[di],dl
push ax
push bx
push cx
push dx
mov bp, offset char
mov dh,00h
mov al, 1
mov bh, 0
mov bl, 1111_0000b
mov cx, 1; calculate message size.
mov dx,0000h
mov ah, 13h
int 10h
mov dl, 20h
mov ah, 02h
int 21h
pop dx
pop cx
pop bx
pop ax
add bx, 1
add cl, 1
cmp cl,15
jz nextRow
jnz printArray
finproc:
ret
printArrays endp
nwLine PROC
MOV AH,02h
MOV DX,0Ah; imprime asscii 10 (nueva linea)
INT 21h
MOV DX,0Dh; imprime asscii 13 (retorno de carro)
INT 21h
RET
nwLine ENDP
valueInArray proc
mov flag, 0
mov di,0001h
iterar:
mov dh, indx[di]
cmp dh,20h
jz finvalueproc
cmp bl,dh
jz found
add di,1
jmp iterar
found:
mov flag,1
jmp finvalueproc:
finvalueproc:
ret
valueInArray endp
exit:
end
As you can see, the array 'indx' have the positions of the chars (The first number is the effective lenght of said array) that I want to highlight so I check if bx is in the position of said character to print it highlighted.
I have two problems at the moment, the first one is the highlighted characters are printing in a kinda random position and that messes up the rest, but I think I know why the position of the highlighted character that prints is wrong, because the interrupt that I use uses dh and dl as positioners but I do not know how to make it so it continues the flow of the rest. The second problem is that the character that prints is wrong, if you run it and check the variable char, it has an 'Z' but it prints a 'T'. I really need help. Pretty please. :(
indx db 5,11,26,41,45 dup (' ')
It could be that this line is not what you think it is!
Reading your explanation I think you really meant:
indx db 5, 11, 26, 41, 45, ' '
That is the length of the array which is 5, then followed by 4 offsets to the highlighted characters and 1 space character as a list terminator.
the first one is the highlighted characters are printing in a kinda random position and that messes up the rest, but I think I know why the position of the highlighted character that prints is wrong, because the interrupt that I use uses dh and dl as positioners but I do not know how to make it so it continues the flow of the rest.
Because your code to output the highlighted character uses mov dx,0000h, the BIOS function 13h places the character in the upperleft corner of the screen and the other, 'normal' characters will continue from there.
All you have to do is to ask BIOS where the cursor is at that moment using function 03h:
Replace
mov cx, 1; calculate message size.
mov dx,0000h
mov ah, 13h
int 10h
by
mov ah, 03h ; BIOS.GetCursorAndConfiguration
int 10h ; -> CX DX
mov cx, 1 ; message size
mov ah, 13h ; BIOS.WriteString
int 10h
Function 13h fetches from ES:BP. Did you setup the ES segment register?
The second problem is that the character that prints is wrong, if you run it and check the variable char, it has an 'Z' but it prints a 'T'.
Probably resolving the first problem will also resolve the second one.
There's a better, less convoluted way to output your highlighted character.
printSpecial:
push ax
push bx
push cx
mov cx, 1 ; ReplicationCount
mov bx, 00F0h ; DisplayPage 0, Attribute BlackOnBrightWhite (11110000b)
mov al, dl ; Character
mov ah, 09h ; BIOS.WriteCharacterAndAttribute
int 10h
mov ah, 0Eh ; BIOS.TeletypeCharacter
int 10h
pop cx
pop bx
pop ax
...
Function 09h will write your character with the colors that you need, and then function 0Eh will advance the cursor normally.
I managed to write this code for turbo debugger in assembly language which is meant to sort 10 integer numbers read from the keyboard and display them in ascending order but it keeps looping B to infinite..
The code is :
.model small
.stack 100h
.data
strg1 DB 'Insert numbers: $'
strg2 DB 'Sorted numbers: $'
Arr Db 10 dup(?)
v dw ?
.code
main proc
mov ax,#data
mov ds,ax
mov ah,9
lea dx,strg1
int 21h
mov dl,0ah
mov ah,2
int 21h
;inputs
mov di,0
mov cx,10
Input_loop:
mov ah,1
int 21h
mov arr[di],al
mov dl,0ah
mov ah,2
int 21h
inc di
loop Input_loop
mov v,0
sort:
mov di,0
mov cx,10
sub cx,v
B:
mov al,Arr[di]
cmp al,Arr[di+1]
jng C
mov al,Arr[di]
xchg al,Arr[di+1]
mov Arr[di],al
c:
inc di
loop B
inc v
cmp v,10
jne sort
;Output
mov ah,9
lea dx,strg2
int 21h
mov dl,0ah
mov ah,2
int 21h
mov di,0
mov cx,10
Output_loop:
mov dl,Arr[di]
mov ah,2
int 21h
inc di
mov dl,0ah
mov ah,2
int 21h
loop output_loop
mov ah,4ch
int 21h
main endp
end main
It is running perfectly, I can enter my desired numbers to be sorted, and then when it reaches c: , it just keeps looping B to infinite and it really makes me mad . Do you have any idea what went wrong and how can I fix it ?
Arr Db 10 dup(?)
v dw ?
In an array that has 10 elements, you can do 9 pairwise comparisons at most.
Your code does 10 comparisons and will move whatever byte is stored after the array, and that is probably a zero, down in memory!
Initialize v at 1:
mov v, 1
sort:
This is the only modification that I made and your program ran perfectly in DOSBox. I assembled the source using TASM 4.1 followed by TLINK
A better BubbleSort
Don't use BubbleSort, better algorithms exist! :-)=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Better use a register like SI instead of a memory based variable v.
Use downcounting for the outer loop count.
Because your elements are byte-sized, you can read and write two elements together.
Keep addressing modes simplest/shortest (using [di] instead of Arr[di]).
Avoid the slow LOOP instruction.
Use meaningful names for your labels.
Avoid using XCHG between a register and memory.
Use unsigned conditional jumps after comparing unsigned quantities like characters "0" to "9" (using jna instead of jng).
mov si, 10-1
Outer:
mov di, offset Arr
mov cx, si
Inner:
mov ax, [di]
cmp al, ah
jna Skip
xchg al, ah
mov [di], ax
Skip:
inc di
dec cx
jnz Inner
dec si
jnz Outer
I was trying to do a palindrome check program using masm and used the below code but I always got not palindrome as output, not able to figure it out why. Please help to modify the code. The code is given below for further clarification.
Thanks in advance.
read macro
mov ah,01h
int 21h
endm
write macro
mov ah,02h
int 21h
endm
assume cs:code,ds:data
data segment
a db 20 dup(?)
b db 20 dup(?)
msg1 db "enter text: $"
msg2 db "reverse string is: $"
msg3 db " palindrome$"
msg4 db " not palindrome$"
data ends
code segment
start:mov ax,data
mov ds,ax
mov es,ax
mov cx,0000h
lea si,a
lea dx,msg1
mov ah,09h
int 21h
r:read
cmp al,0dh
je l
mov [si],al
inc si
inc cx
jmp r
l:dec si
lea di,b
mov ax,cx
l1:mov dl,[si]
mov [di],dl
inc di
dec si
loop l1
l2:
mov cx,ax
lea si,b
lea dx,msg2
mov ah,9h
int 21h
w:mov dl,[si]
write
inc si
loop w
mov cx,ax
cld
lea si,a
lea di,b
l4:cmpsb
jne l5
loop l4
lea dx,msg3
mov ah,09h
int 21h
mov ah,4ch
int 21h
l5:lea dx,msg4
mov ah,09h
int 21h
mov ah,4ch
int 21h
code ends
end start
whatever is input string it gives not a palindrome.
Instead of doing mov ax,cx use mov bx,cx as ah is used in interrupts it might cause some problems. And every where mov cx,ax is there use mov cx,bx ....now it will be correct.
It might seem funny that I answered my own question but I figured this now and didn't delete cause it might help others from not doing the same...
how to show string 10 times in assembly language?
Here is my code
.model small
.stack 100h
.data
msg db 'rashed $'
.code
main proc
mov ax,#data
mov ds,ax
lea dx,msg
mov ah,9 ;string output
int 21h
mov dx,0 ;dx counts characters
mov ah,9 ;prepare for read
int 21h
while_:
cmp al,0dh ;carriage return?
je end_while ;yes exit
inc dx ;not carrage return,increament count
int 21h ;read character
jmp while_ ;loop back
end_while:
exit:
mov ah,4ch
int 21h
main endp
end main
output is:
i want to show this string 10 times but the string subtracts??
how to show that 10 times??
mov dx,0 ;dx counts characters
To show the same text a number of times, choose a counter register different from the registers that are required to perform the output (In your case AX and DX). I suggest putting the counter in CX.
mov cx, 11
while_:
dec cx ;Change counter
jz end_while ;Exit after 10 iterations
mov ah, 9
int 21h ;Print string
jmp while_ ;Loop back
end_while:
Because a while-loop tests the condition first, I assigned 11
instead of 10.