this is my code:
.model small
.stack 100h
.data
A db 2,-5,3,4,-8
N equ 5
.code
mov ax, #data
mov ds, ax
mov si,offset A
mov cl,1
start:
cmp cl,N
je sof
mov al,[si]
cmp al,[si+1]
jg change
jmp next
change:
mov ah,al
mov al,[si+1]
mov [si],ah
mov [si+1],al
jmp next
next:
inc si
inc cl
jmp start
sof:
mov ah,9
mov cx, offset A
int 21h
.exit
end
i get a weird out put a lot of weird characters :/
You need to add 30h to a number in range 0 through 9 in order to display an ascii character. To display a character, use
;al = digit to display
mov dl,al
add dl,030h
mov ah,02 ;display character (in dl)
int 21h
Related
In the program for to find out no. of vowels in a string. I got stuck at "Enter a string:" ?? why? even tho the compiler says everything okay.
program to count the no. of vowels in a string.
;;;;;;;PROGRAM TO CHECK NO. OF VOWELS IN A STRING;;;;;
.model small
.stack 100h
.data
vowels db 'AEIOUaeiou$'
msg1 db 'Enter a string:$'
msg2 db 'The string is:$'
msg3 db 'No of vowels are:$'
string db 50 dup('$')
count db ?
.code
main proc
mov ax, #data
mov ds, ax
mov es, ax
lea dx,msg1
mov ah,09h ;for displaying enter a string
int 21h
lea di,string
cld
xor bl,bl
input:mov ah,01 ; stuck here, at taking input, why??
cmp al, 13
je endinput
stosb
inc bl
jmp input
endinput:cld
xor bh,bh
lea si,string
vowelornot: mov cx,11
lodsb
lea di,vowels
repne scasb
cmp cx, 00
je stepdown
inc bh
stepdown: dec bl
jnz vowelornot
mov ah,06 ;;;THIS FOR CLEARING SCREEN I GUESS
mov al,0 ;;;
int 10h
lea dx,msg2
mov ah,09
int 21h
mov dl, 13 ;;; NEW LINE
mov ah, 2
int 21h
mov dl, 10
mov ah, 2
int 21h
lea dx,string
mov ah, 09
int 21h
mov dl,13 ;;;NEW LINE
mov ah,2
int 21h
mov dl,10
mov ah,2
int 21h
lea dx, msg3
mov ah,09
int 21h
mov dl,13 ;;;NEW LINE
mov ah,2
int 21h
mov dl,10
mov ah,2
int 21h
mov count, bh
mov dh, count ;;; DH = VOWEL COUNT
mov ah,09
int 21h
mov ah, 4ch ;;; EXIT
int 21h
main endp
end
Multiple errors
input:mov ah,01 ; stuck here, at taking input, why??
cmp al, 13
Here your code is missing the int 21h instruction!
input:
mov ah,01
int 21h
cmp al, 13
xor bl,bl
input:
stosb
inc bl
jmp input
You're using BL to count the number of characters in the input string but the example you wrote needs much more than the 255 maximum that this byte-sized register can give you. This must fail!
Moreover the buffer that you've setup is limited to 50 bytes. No way you could store there such a long input.
lea si,string
vowelornot: mov cx,11
lodsb
lea di,vowels
repne scasb
cmp cx, 00
je stepdown
inc bh
stepdown: dec bl
jnz vowelornot
This is too complicated. Just interpret the ZeroFlag and don't look at CX at all. You don't need to terminate the vowels text with a "$" anymore (use CX=10).
lea si,string
vowelornot:
lodsb
mov cx,10
lea di,vowels
repne scasb
jne stepdown
inc bh ;Vowel found +1
stepdown:
dec bl
jnz vowelornot
mov ah,06 ;;;THIS FOR CLEARING SCREEN I GUESS
mov al,0 ;;;
int 10h
Sure, function 06h can clear the screen but you need to provide all of the required arguments. Upperleftcorner in CX, Lowerrightcorner in DX and Displaypage in BH.
mov dx, 184Fh ;(79,24) If screen is 80x25
xor cx, cx ;(0,0)
mov bh, 0
mov ax, 0600h
int 10h
lea dx,string
mov ah, 09
int 21h
This will fail because you did not put a "$" character at the end of the inputted string.
And if you're going to output a CRLF directly afterwards, why not add it to the buffer?
jmp input
endinput:
mov ax, 0A0Dh <-- ADD THIS
stosw <-- ADD THIS
mov al, "$" <-- ADD THIS
stosb <-- ADD THIS
xor bh,bh
You print msg2 and msg3 followed by a CRLF. Why don't you append it in the definition? No more need to output it separately.
msg2 db 'The string is:', 13, 10, '$'
msg3 db 'No of vowels are:', 13, 10, '$'
mov count, bh
mov dh, count ;;; DH = VOWEL COUNT
mov ah,09
int 21h
To output the count and provided it is a number in the range from 0 to 9, you need to convert the number into a character. Just add 48 or '0'.
Don't use function 09h. It requires an address and you clearly want to use a character.
mov dl, bh ;Count of vowels [0,9]
add dl, '0'
mov ah, 02h
int 21h
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
I am stuck at point where I need to read 3 numbers from created buffer of text file. I've tryed reading every byte, but no luck if the number is bigger than 9.
Steps that I do:
Open text file
Read file's content into created buffer
Put every buffers byte into different register (ax, bx, cx, dx).
The problem is, it reads 1 byte (mov ax, buffer[0]) at a time: if my text file is (10 10 1), it reads 1 then 0 then space symbol(ascii 20) and so on. Should I do cycle that converts and adds every byte to one register while it doesn't detect space symbol? Or is there a possibility to read whole number at one time? Here's the code:
.model small
bufferLen equ 16
.stack 100h
.data
duom db "duom.txt", 0
fident dw 0
buffer db bufferLen dup (?)
.code
start:
mov dx, #data
mov ds, dx
mov bx, 81h
tikrinam: ; not important
mov ax, es:[bx]
inc bx
cmp al, 13
je openf
cmp al, 20h
je tikrinam
cmp ax, "?/"
jne openf
mov ax, es:[bx]
cmp ah, 13
je abouthlp
jmp openf
abouthlp:
mov dx, offset about
mov ah, 09h
int 21h
jmp ending
openf:
mov ah, 3Dh
mov al, 0
mov dx, offset duom
int 21h
mov [fident], ax
readf:
mov ah, 3Fh
mov bx, [fident]
mov cx, bufferLen
mov dx, offset buffer
int 21h
mov al, buffer[0]
mov bl, buffer[1]
mov cl, buffer[2]
I've found the solution if anyone is having same problem:
changeNumbers:
push ax
mov ax, 0
cmp cl, 0
je change
temp1:
mov ch, 0
mov cl, buffer[si]
inc si
cmp cl, 32
je changeNumbers
cmp cl, 0
je changeNumbers
sub cl, 48
mul abc
add ax, cx
jmp temp1
Basically what I did was read every byte and if the number is >9 then add cx to ax and multiply it by 10. Then just push it to stack for further usage. Brain is an amazing thing, I'd say.
i am trying to make a simple calculator in TASM, its not done yet, i am trying to figure out addition part but i am stuck because of Operands type do not match, here is what i have;
;FILENAME: SimpleClc.asm
;FILE FORMAT: EXE
PAGE 55,132
.386
STACK_SEG SEGMENT STACK USE16
DB 100 DUP(?)
STACK_SEG ENDS
DATA_SEG SEGMENT 'DATA' USE16
ADDITION MACRO Result,Char1,Char2
MOV AX,Char1
CWD
ADD AX,Char2,
MOV Result,AX
ENDM
SUBTRACTION MACRO Char1, Char2
SUB Char1,Char2
ENDM
DIVISION MACRO Char1, Char2
DIV Char1,Char2
ENDM
MULTIPLICATION MACRO Char1, Char2
MUL Char1,Char2
ENDM
Mainmsg DB 'Please enter a algebraic command line: $'
ErMessage DB 'Error!!', 0DH, 0AH
DB 'INPUT FORMAT:Operand1 Operator Operand',0DH, 0AH
DB 'Operand: Decimal Numbers',0DH, 0AH
DB 'Operator: + -'
INCHAR DB 21
Res DB 10 dup('$')
INCDAT DB 21 dup('$')
VarX DB 10 dup('$')
VarY DB 10 dup('$')
DATA_SEG ENDS
CODE_SEG SEGMENT PARA 'CODE' PUBLIC USE16
ASSUME CS:CODE_SEG, DS:DATA_SEG, SS:STACK_SEG
MAIN PROC FAR
PUSH DS ;INITIATE THE PROGRAM
XOR AX,AX
PUSH AX
MOV AX,DATA_SEG
MOV DS,AX
AGAIN:
LEA DX,Mainmsg ;PRINT MESSAGE
MOV AH,9
INT 21H
MOV DX, OFFSET INCHAR
MOV AH,0AH
INT 21H
MOV DX, OFFSET INCHAR
MOV AH,0AH
INT 21H
LEA DX,INCDAT ;Writing the incoming input
MOV AH,9
INT 21H
MOV DI,OFFSET INCDAT
MOV AL, [DI]
CMP AL, 9
JLE OPERAND ; jump if less or equal
JG ERRORMESSAGE ; jump if not less or equal
INC DI
OPERAND:
MOV AL, [DI]
CMP AL, '+'
JE LASTOPERAND
CMP AL, '-'
JE LASTOPERAND
CMP AL, '*'
JE LASTOPERAND
CMP AL, '/'
JE LASTOPERAND
JMP ERRORMESSAGE
INC DI
LASTOPERAND:
MOV AL, [DI]
CMP AL, 9
JLE OPERATION ; jump if less or equal
JG ERRORMESSAGE ; jump if not less or equal
OPERATION:
CMP AL, '+'
JE ADDITION1
JMP AGAIN
ADDITION1:
MOV DI,OFFSET INCDAT
MOV AL,[DI]
MOV VarX,AL
MOV AL,[DI+2]
MOV VarY,AL
ADDITION Res,VarX,VarY
JMP AGAIN
CMP AL, '-'
JE SUBTRACTION1
JMP AGAIN
SUBTRACTION1:
CMP AL, '*'
JE MULTIPLICATION1
JMP AGAIN
MULTIPLICATION1:
JMP AGAIN
CMP AL, '/'
JE DIVISION1
JMP AGAIN
DIVISION1:
ERRORMESSAGE:
LEA DX,ErMessage ;PRINT MESSAGE
MOV AH,9
INT 21H
MAIN ENDP
CODE_SEG ENDS
END MAIN
I know it looks quite messy right now, it is just because i am trying bunch of things at the same time, btw my calculator will not calculate results that are greater than 10. Thanks for help.Any comment will be appreciated.
Ups, it is hard to digit all the linenumbers.
To place code inside the data segment is not the best idea.
For what this following instruction are good?:
PUSH DS ; pushing the old address of DS to the stack
XOR AX,AX
PUSH AX ; pushing a zero word to the stack
And at last how to terminate the programm?
I am not sure, but maybe the errors occur for using labelnames that starts similar like the names of assembler mnemonics.
And why using the input function one after another for to override the same buffer?
MOV DX, OFFSET INCHAR
MOV AH,0AH
INT 21H
MOV DX, OFFSET INCHAR
MOV AH,0AH
INT 21H
I have this code to copy the array "NUMBERS" to "DEST" such that no number will repeat (in this case it should be : 1,2,5,4,7)
The code works but now I need to print the array "DEST". How can I do that ?
data segment
NUMBERS db 1,2,1,1,1,5,5,4,7,7
DEST dt ?
data ends
code segment
assume ds:data, cs:code
start: mov ax, data
mov ds, ax
mov ax, 0a0ah
mov di, offset NUMBERS
mov bx, 0h
loop2:mov cl, [di]
mov si, offset DEST
mov ch, [si]
loop1:cmp ch, cl
je dontadd
inc si
mov ch, [si]
dec ah
jnz loop1
mov si, offset DEST
add si, bx
inc bx
mov [si], cl
dontadd:mov ah, 0ah
inc di
dec al
jnz loop2
mov ah, 4ch
int 21h
code ends
end start
You can use INT 21h, AH=02h to print a single character to STDOUT.
MOV CX,10
MOV SI,OFFSET DEST
print:
MOV DL,[si]
OR DL,DL
JE done
ADD DL,'0' ; <-- Convert numeric value in DL into ASCII code
MOV AH,02h
INT 21h
MOV DL,' ' ; Throw in a space to make things pretty
INT 21h
INC SI
LOOP print
done:
If elements in NUMBERS have values over 9 then you need more elaborate conversion of the numeric values into ASCII.
First convert numbers to string then print them.You can use this two macros for printing numbers:
printstr macro str
push ax
push dx
lea dx,str
mov ah,9
int 21h
pop dx
pop cx
endm
printnum macro n
local o,w,s,n5,lb1,lb2,lb3
pusha
push si
push di
jmp w
s db 7 dup('$')
w:
mov si,0
mov cx,7
o:mov s[si],'$'
inc si
loop o
mov si,0
xor ax,ax
mov ax,n
xor dx,dx
cmp ax,0
jge n5
mov bl,'-'
mov s[si],bl
inc si
neg ax
n5:mov cx,10
div cx
or dl,30h
mov s[si],dl
xor dx,dx
inc si
cmp ax,0
jne n5
mov si,0
cmp s[si],'-'
jne lb1
inc si
lb1:mov di,si
lb3:cmp s[si],'$'
je lb2
mov al,s[si]
push ax
inc si
jmp lb3
lb2:pop ax
mov s[di],al
inc di
cmp di,si
jl lb2
printstr s
pop di
pop si
popa
endm