Define a string array using NASM - Prototype give the number of days in a month - arrays

Well as the title said , I am working on a NASM project: the idea is simple , I need to take a month from input (string) and give the number of day (using cases regarding numbers). Until now I spent the day dealing with reading/printing and finally comparing 2 strings , which I could do after some struggles and thanks to some old questions I've found here and on other forums.My current problem is that I need to put the months (names) in an array so I could do the comparing with a loop, I saw on another answer that I could label the 'array' like this:
label: db str1,str2
I tried that and when I try printing with just the label I get only the last month (I tried label+i but I still get the same thing)
Well, here is a part of my code:
segment .data
org 100h
msg db "a"
mon1 db "janvier",0
mon2 db "fevrier",0
mon3 db "mars",0
mon4 db "avril",0
mon5 db "mai",0
mon6 db "juin",0
mon7 db "juillet",0
mon8 db "aout",0
mon9 db "septembre",0
mon10 db "octobre",0
mon11 db "novembre",0
mon12 db "decembre",24h
mo dw 1,2,3,4,5,6,7,8,9,10,11,12
mon:
dw mon1,mon2,mon3,mon4,mon5,mon6,mon7,mon8,mon9,mon10,mon11,mon12
segment .code
mov dx,mon
mov ah,09h
int 21h
edit2: I tried the solution given by #ecm , I had to make a few change because It gave me some errors then after i could finally run it It went to error, Here is the whole code:
segment .code
display_month:
; takes month 1 to 12 in ax
dec ax ; make number 0-based
cmp ax,amount
jae error ; if out of range -->
add ax, ax ; make it an index into a word array
mov bx, ax ; use bx for addressing memory
mov dx, word [mon+ bx] ; access array entry
mov di, dx
mov cx, -1
mov al, 0
repne scasb
not cx
dec cx ; string length
mov bx, 1
mov ah, 40h
int 21h ; write to stdout
clc ; indicate not error
mov dx,msg1
mov ah,09h
int 21h
mov ah,0Ah
mov dx, len ;start of buffer
int 21h
mov ah,02h
mov dl,10
int 21h
mov dl,13
int 21h
mov bx,act
mov dx,buffer
add dl,byte [bx]
mov bx,dx ; move pointer into BX
mov byte [bx],24h ; put the $ there.
; compare input with msg variable(a placeholder for the moment ) I want to compare with the mon array values , and then use the index as an argument to call the cond procedure.
mov ax,msg
mov si,ax
mov ax,buffer
mov di,ax
cmpsb
jz Yep ; if strings equal goto Yep
jmp Nope ; goto Nope
Yep:
mov dx,good
mov ah,9
int 21h ; tell the user it's good
Nope:
mov dx,bad
mov ah,9
int 21h ; tell the user it's bad
end:
mov ah,4Ch
int 21h
ret
error:
stc
retn
cond:
cmp ax,2
je fev
cmp ax,7
jg odd
jle even
else: mov bx,31
jmp endif
fev: mov bx,28
odd: test ax,1
jnz trente
jmp else
even: test ax,1
jp trente
jmp else
trente: mov bx,30
endif: ret
segment .data
org 100h
;; variables declaration
msg1 db "Veullez entrer un mois:",24h
msg db "a",24h
mon1: db "janvier",0
mon2: db "fevrier",0
mon3: db "mars",0
mon4: db "avril",0
mon5: db "mai",0
mon6: db "juin",0
mon7: db "juillet",0
mon8: db "aout",0
mon9: db "septembre",0
mon10: db "octobre",0
mon11: db "novembre",0
mon12: db "decembre",0
good db "Bon choix!",24h
bad db "Mauvais choix!",24h
mon:
start:
dw mon1,mon2,mon3,mon4,mon5,mon6,mon7,mon8,mon9,mon10,mon11,mon12
tend:
len db 254 ; a fair amount of space
act db 0 ; will be filled with actual amount of chars received
buffer times 254 db 0
size equ tend - start
amount equ size / 2
I forgot to add how I am compiling , well I am using dosbox to run .com files , because they don't work on windows 10 , and I use the command : nasm name.asm -o name.com to create the .com file and then I just open it in dos.
EDIT: Well I struggled a lot to make that happen , I couldn't do it even thought I tried different ways , the last thing I went with was to use the first month and keeping adding the size of months to pass to the other ones (i.e mon1+8 gives me mon2 ...) but then I encountered with the difference in sizes , so I changed all the months to just 3 letters (4 for june) so I could move with multiples of 4 but then I couldn't go all the way to the end .. So after that I just decided to use the mon(i) by calling the names and repeating the manoeuvre , which seemed to work thought I encountered a problem with comparing (I am still trying to figure out) , well here is the last version until I figure out how to fix that.The problem at this moment is that even if I type something different than the mon1 to mon12 I get this:Le mois de 'input' est de 30 jours while normally it should take me back to the start of the nope label.
segment .code
org 100h
mov dx,msg1
mov ah,09h
int 21h
here: mov ah,0Ah
mov dx, len
int 21h
mov ah,02h
mov dl,10
int 21h
mov dl,13
int 21h
mov bx,act
mov dx,buffer
add dl,byte [bx]
mov bx,dx
mov byte [bx],24h
jmp comp
yep:
mov dx,g1
mov ah,09h
int 21h
mov dx,buffer
int 21h
mov dx,g2
int 21h
mov ax, [i]
call cond
mov ah,02h
mov dl,bh
int 21h
mov dl,bl
int 21h
mov dx,g3
mov ah,09h
int 21h
jmp end
comp: mov bx,0
mov [i],bx
jan: call inct
mov bx,buffer
mov si,bx
mov bx,mon1
mov di,bx
cmpsb
jz yep
fevr: call inct
mov bx,buffer
mov si,bx
mov bx,mon2
mov di,bx
cmpsb
jz yep
mar: call inct
mov bx,buffer
mov si,bx
mov bx,mon3
mov di,bx
cmpsb
jz yep
avr: call inct
mov bx,buffer
mov si,bx
mov bx,mon4
mov di,bx
cmpsb
jz yep
mai: call inct
mov bx,buffer
mov si,bx
mov cx,mon5
mov di,cx
cmpsb
jz yep
juin: call inct
mov bx,buffer
mov si,bx
mov bx,mon6
mov di,bx
cmpsb
jz yep
jmp jui
jui: call inct
mov cx,buffer
mov si,cx
mov cx,mon7
mov di,cx
cmpsb
jz yep
aout: call inct
mov cx,buffer
mov si,cx
mov cx,mon8
mov di,cx
cmpsb
jz yep
jmp sep
sep: call inct
mov bx,buffer
mov si,bx
mov cx,mon9
mov di,cx
cmpsb
jz yep
jmp oct
oct: call inct
mov bx,buffer
mov si,bx
mov cx,mon10
mov di,cx
cmpsb
jz yep
jmp nov
nov: call inct
mov bx,buffer
mov si,bx
mov cx,mon11
mov di,cx
cmpsb
jz yep
jmp dect
dect: call inct
mov bx,buffer
mov si,bx
mov cx,mon12
mov di,cx
cmpsb
jz yep
jmp nope
nope:
mov dx,bad
mov ah,9
int 21h
jmp here
end:
mov ah,4Ch
int 21h
ret
inct:
push bx
mov bx,[i]
inc bx
mov [i],bx
pop bx
ret
cond:
cmp ax,2
je fev
cmp ax,6
je th
cmp ax,8
je th
cmp ax,7
jg odd
jle even
else: mov bl,'1'
mov bh,'3'
jmp endif
fev: mov bl, '8'
mov bh,'2'
jmp endif
th: jmp else
odd: test ax,1
jnz trente
jmp else
even: test ax,1
jp trente
jmp else
trente: mov bh,'3'
mov bl,'0'
endif: ret
segment .data
i db 0
msg1 db "Veullez entrer un mois:",24h
mon1: db "janvier",24h
mon2: db "fevrier",24h
mon3: db "mars",24h
mon4: db "avril",24h
mon5: db "mai",24h
mon6: db "juin",24h
mon7: db "juillet",24h
mon8: db "aout",24h
mon9: db "septembre",24h
mon10: db "octobre",24h
mon11: db "novembre",24h
mon12: db "decembre",24h
g1 db "Le mois de",20h,24h
g2 db 20h,"est de",20h,24h
g3 db 20h,"jours",24h
bad db "Le mois saisi n'est pas correct!",10,13,"Veuillez entrer un autre mois:",24h
len db 254 ; a fair amount of space
act db 0 ; will be filled with actual amount of chars received
buffer times 254 db 0

Try this:
segment .code
display_month:
; takes month 1 to 12 in ax
dec ax ; make number 0-based
cmp ax, montab.amount
jae .error ; if out of range -->
add ax, ax ; make it an index into a word array
mov bx, ax ; use bx for addressing memory
mov dx, word [montab + bx] ; access array entry
mov di, dx
mov cx, -1
mov al, 0
repne scasb
not cx
dec cx ; string length
mov bx, 1
mov ah, 40h
int 21h ; write to stdout
clc ; indicate not error
retn
.error:
stc
retn
segment .data
mon1: db "janvier",0
mon2: db "fevrier",0
mon3: db "mars",0
mon4: db "avril",0
mon5: db "mai",0
mon6: db "juin",0
mon7: db "juillet",0
mon8: db "aout",0
mon9: db "septembre",0
mon10: db "octobre",0
mon11: db "novembre",0
mon12: db "decembre",0
align 2
montab:
.:
dw mon1
dw mon2
dw mon3
dw mon4
dw mon5
dw mon6
dw mon7
dw mon8
dw mon9
dw mon10
dw mon11
dw mon12
.end:
.size equ .end - .
.amount equ .size / 2
You could use 12 as the hardcoded array length in this case. But using equates for the length and amount of entries is useful for static data arrays more generally.
ETA: I added alignment for the table, which is good for performance. Not needed but it doesn't cost much.
Note that I dropped the org directive from my example. This is because I am presenting just one function that should be called from other program logic. If you're assembling into a simple style flat .COM executable for 86-DOS, you still need to include the org 256 at some point.
Here's a breakdown of your question's attempt:
msg db "a"
This seems like an unused leftover.
mon1 db "janvier",0
mon2 db "fevrier",0
mon3 db "mars",0
mon4 db "avril",0
mon5 db "mai",0
mon6 db "juin",0
mon7 db "juillet",0
mon8 db "aout",0
mon9 db "septembre",0
mon10 db "octobre",0
mon11 db "novembre",0
These are all fine, they define ASCIZ strings. (The Z stands for zero-terminated.)
mon12 db "decembre",24h
This one uses a different terminator, in this case the dollar sign (24h = 36). It is not appropriate to mix terminators between array entries. Either use all ASCIZ or all CP/M-style dollar-terminated strings.
mo dw 1,2,3,4,5,6,7,8,9,10,11,12
This is useless. If you wanted to map a number from 1 to 12 as index into this array, the original value would be found at that array entry. If the entries had different numbers this type of array could be useful, but not with identity mapping.
mon:
dw mon1,mon2,mon3,mon4,mon5,mon6,mon7,mon8,mon9,mon10,mon11,mon12
This is essentially correct. (I put each entry on its own line and prepended the align directive, but neither is absolutely necessary.)
mov dx,mon
mov ah,09h
int 21h
This loads the address of your message table into dx then passes dx to interrupt 21h function 09h. This function expects a dollar-terminated string, so only your December string would work. More importantly, it will try to display the literal bytes that make up your array. You need to, instead, dereference a pointer to one of your array's entries to load the address stored therein, which is the address of the associated message string.

Related

Retrieve data from an array

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

Printing an array but specific values highlighted {emu8086}

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.

Sort 10 integer numbers read from keyboard and display in ascending order

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

masm palindrome check output dilemma

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...

TASM: Generating a simple calculator

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

Resources