can someone pls help idk what is wrong with this tasm code - tasm

.model small
.stack 100h
.data
; Define the data structure for the events
event struct
name db 32 dup(?)
date db 11 dup(?)
time db 8 dup(?)
location db 32 dup(?)
description db 256 dup(?)
event ends
events event 10 dup(<>)
num_events dw 0 ; Counter to keep track of the number of events in the array
menu db "Which type of events do you want to list?", 0Dh, 0Ah, "1. Workshops", 0Dh, 0Ah, "2. Competitions", 0Dh, 0Ah, "3. Activities", 0Dh, 0Ah, 0
menu_len equ $ - menu
.code
main proc
mov ax, #data
mov ds, ax
; Load the events from the file
call load_events
; Display the menu and get the user's choice
mov ah, 09h ; DOS system call to print a string
mov dx, offset menu
int 21h
mov ah, 01h ; DOS system call to read a character from the keyboard
int 21h
sub al, '0' ; Convert the character to a number
mov bl, al ; Save the user's choice in BL
; Loop over all the events of the chosen type and print their information
mov cx, num_events
mov si, offset events
print_loop:
cmp bl, 1
je print_workshops
cmp bl, 2
je print_competitions
cmp bl, 3
je print_activities
; If the user didn't choose a valid option, exit the program
mov ax, 4c00h ; DOS system call to terminate the program
int 21h
print_workshops:
cmp [si].event.name, "Workshop"
jne next_event
call print_event
next_event:
add si, sizeof event ; move to the next event in the data structure
loop print_loop
print_competitions:
cmp [si].event.name, "Competition"
jne next_event2
call print_event
next_event2:
add si, sizeof event ; move to the next event in the data structure
loop print_loop
print_activities:
cmp [si].event.name, "Activity"
jne next_event3
call print_event
next_event3:
add si, sizeof event ; move to the next event in the data structure
loop print_loop
i been trying to make this code run but there is something wrong i can't figure out

Related

No output from 8086 program when running ml program.asm in DOSBox

I got this code from the Geeks-for-Geeks site, but there were lots of indentation errors, I changed the code to the following but, when running the code using MASM and DOSBox it's giving no output.
The Output I should get, According to the site I should get 20 but I get nothing, the code is saved as pro.asm, and I'm using DOSBox version 0.74.
For getting the o/p in the DOSBox I did,
mount c c:\8086
c:
ml pro.asm
Code:
;8086 program to convert a 16-bit decimal number to octal
.MODEL SMALL
.STACK 100H
.DATA
d1 dw 16
.CODE
MAIN PROC FAR
MOV ax,#DATA
MOV ds,ax
;load the value stored in variable d1
MOV ax, d1
;convert the value to octal
;print the value
CALL PRINT
;interrupt to exit
MOV AH,4CH
INT 21H
MAIN ENDP
PRINT PROC
;initialize count
MOV cx,0
MOV dx,0
label1: ;if ax is zero
cmp ax,0
je print1
;initialize bx to 8
mov bx, 8
;divide it by 8 to convert it to octal
div bx
;push it in the stack
push dx
;increment the count
inc cx
;set dx to 0
xor dx,dx
jmp label1
print1: ;check if count is greater than zero
cmp cx,0
je exit
;pop the top of stack
pop dx
;add 48 so that it
;represents the ASCII
;value of digits
add dx,48
;interrupt to print a
;character
mov ah,02h
int 21h
;decrease the count
dec cx
jmp print1
exit : ret
PRINT ENDP
END MAIN
The output I'm getting can be seen below
Your code looks okay. Your screenshot shows you have only assembled and linked the code but not actually run it. To run it type:
pro.exe

How to print an integer stored in a variable

So I have a program in 8086 assembly that allows the user to enter 2 digits, store them in a variable and then print out the number:
data segment
broj db ?
ends
stack segment
dw 128 dup(0)
ends
code segment
mov ax, data
mov ds, ax
mov es, ax
mov ah, 1h
int 21h
sub al, 48d
mov bl, 10d
mul bl
mov broj, al
mov ah, 1h
int 21h
sub al, 48d
add broj, al
mov dl, broj
sub dl, 48d
mov ah, 2h
int 21h
mov ax, 4c00h
int 21h
ends
However whenever I enter a number for example 21 it doesn't give me the number instead it gives me ASCII Code for that value.
Can anyone help?!
However whenever I enter a number for example 21 it doesn't give me the number instead it gives me ASCII Code for that value.
If you feed (input) your program a number that consists of 2 digits, then you'll have to print also 2 digits! Currently your code contains just the one character output function.
First divide the number in broj by 10 giving a quotient (in AL) and a remainder (in AH).
Convert the quotient to character (Add 48) and print it.
Convert the remainder to character (Add 48) and print it.
Example:
mov al, broj
mov ah, 0
mov bl, 10
div bl
add ax, "00"
mov dx, ax
mov ah, 02h
int 21h
mov dl, dh
mov ah, 02h
int 21h

Algorithm to assembly x86?

I have been for some days trying to translate an algorithm to assembly x86, and I did it. However I would like to print the final result that it is saved in "tmp", what instruction can I use? (I'm Spanish so I'm sorry if I say something wrong in English).
This is my algorithm:
tmp = NOT(L0)
tmp = tmp AND L1
tmp = NOT(NOT(tmp) OR NOT(L2))
tmp = NOT(tmp OR NOT(L3))
tmp = NOT(tmp + NOT(L4))
if (tmp == L5)
licence = correct
else
licence = incorrect
And this is it in assembly:
LicenceCorrect PROC
push ebp
mov ebp,esp
push ebx
push ecx
push edx
mov ebx, [ebp+8]
mov edx,[ebx]
mov ecx,edx
not ecx
mov edx,[ebx+4]
and ecx,edx
mov edx,[ebx+8]
not edx
not ecx
or ecx,edx
not ecx
mov edx,[ebx+16]
not edx
or ecx,edx
not ecx
;if
mov edx,[ebx]
cmp ecx,edx
jne cons
mov al,0
jmp next
cons:
mov al,1
next:
pop edx
pop ecx
pop ebx
pop ebp
ret
LicenceCorrect ENDP
END
Next code displays a number in AX (made with EMU8086). What MissPaper must do now is insert your procedure (LicenseCorrect) at the end of next code, and call it after "call dollars", then assign the value to AX (remove "12345").
Here it is for 32 bits:
.model small
.stack 100h
.data
buffer db 6 dup(?)
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, #data
mov ds, ax
;FIRST, FILL BUFFER WITH '$' (NECESSARY TO DISPLAY).
mov si, offset buffer
call dollars
;SECOND, CONVERT NUMBER TO STRING.
mov ax, 12345
mov si, offset buffer
call number2string
;THIRD, DISPLAY STRING.
mov dx, offset buffer
call printf
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;-----------------------------------------
;PARAMETER : DX POINTING TO '$' FINISHED STRING.
printf proc
mov ah, 9
int 21h
ret
printf endp
;------------------------------------------
;FILLS VARIABLE WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : SI = POINTING TO STRING TO FILL.
dollars proc
mov cx, 6
six_dollars:
mov bl, '$'
mov [ si ], bl
inc si
loop six_dollars
ret
dollars endp
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : AX = NUMBER TO CONVERT.
; SI = POINTING WHERE TO STORE STRING.
number2string proc
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov dx, 0 ;NECESSARY TO DIVIDE BY BX.
div bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp ax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
number2string endp
end start
Now the 64 bits version (for much bigger numbers in EAX), made with GUI Turbo Assembler x64 (http://sourceforge.net/projects/guitasm8086/):
.model small
.586
.stack 100h
.data
buffer db 11 dup(?)
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, #data
mov ds, ax
;FIRST, FILL BUFFER WITH '$' (NECESSARY TO DISPLAY).
mov esi, offset buffer
call dollars
;SECOND, CONVERT NUMBER TO STRING.
mov eax, 1234567890
mov esi, offset buffer
call number2string
;THIRD, DISPLAY STRING.
mov dx, offset buffer
call printf
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;-----------------------------------------
;PARAMETER : DX POINTING TO '$' FINISHED STRING.
printf proc
mov ah, 9
int 21h
ret
printf endp
;------------------------------------------
;FILLS VARIABLE WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : ESI = POINTING TO STRING TO FILL.
dollars proc
mov cx, 11
six_dollars:
mov bl, '$'
mov [ esi ], bl
inc esi
loop six_dollars
ret
dollars endp
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : EAX = NUMBER TO CONVERT.
; ESI = POINTING WHERE TO STORE STRING.
number2string proc
mov ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov edx, 0 ;NECESSARY TO DIVIDE BY EBX.
div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp eax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ esi ], dl
inc esi
loop cycle2
ret
number2string endp
end start
I didn't add your procedure because it uses the stack and I don't know what values to push before calling it.

Assembler (TASM x64) arrays and elements

I have an array of nine names:
.model tiny
.data
vardas1 db "Rokas",0ah,'$'
vardas2 db "Tomas",0ah,'$'
vardas3 db "Matas",0ah,'$'
vardas4 db "Domas",0ah,'$'
vardas5 db "Augis",0ah,'$'
vardas6 db "Vofka",0ah,'$'
vardas7 db "Marka",0ah,'$'
vardas8 db "Auris",0ah,'$'
vardas9 db "Edvis",0ah,'$'
vardai dw offset vardas1, offset vardas2, offset vardas3, offset vardas4, offset vardas5, offset vardas6, offset vardas7, offset vardas8, offset vardas9
.code
org 100h
I need to read a digit from keyboard, and then I need to print that name. For example I will push 5, and console should write "Augis". BTW, second code block aren't all code, just loop that doesn't work
paieska:
mov dx, offset _comment1 ; Just string name asking user to input digit
mov ah, 9
int 21h
mov j, 00h ; Trying to input the digit from keyboard
mov ah, 01h
mov dl, 0ah
int 21h
mov bx, offset vardai ; Add array "names" to bx register
add bx, cx ; Add cx for indexing
mov dx, [bx] ; Add first array element to dx register
add cx, 2 ; Increasing cx by 2, because I'm using data word not data byte
mov ah, 9 ; Try to print it
int 21h
cmp cx, j ; Try to compare cx (index of array) to mine inputed digit "j"
jne paieska
je end
mov ah, 01h
mov dl, 0ah ;NO NEED FOR THIS - INT21/01 DOES NOT USE DL
int 21h
MOV AH, '1' ; MIN INPUT CHAR
mov bx, offset vardai ; Add array "names" to bx register WELL, ASSIGN ACTUALLY
MOV CX,2 ;NUMBER OF BYTES TO ADD (WORDS, NOT BYTES)
LOOPN:
mov dx, [bx] ; name-pointer array element to dx register
CMP AH,AL ; MATCHING char?
JE PNAME ; YES, PRINT NAME
add bx, cx ; Add cx=2 for next name
inc AH ; next possible character input
CMP AH,'9'+1 ; allowed is '1'..'9'
jne loopn ; in allowed range
; input not 1..9
mov dx, offset errormessage
PNAME:
mov ah, 9 ; Try to print it
int 21h
jmp end
Well, I tried to edit your approach with CAPS, but it became too complicated.
Essentially, you are reading a character from the keyboard using function 01. This character arrives in AL. If all goes well, it should be '1'..'9'. Notice these are the ASCII characters '1'..'9', that is hex 31..39
Next step is to set BX to the start of the table, AH to the minimum character you anticipate and CX to 2 because the table contains words, not bytes.
Now we have a loop. Load X from the table, and check whether AL is equal to AH. If the user input 1, these will be equal, so go print the string.
Otherwise, add 2 to BX to point to the next entry in the table (this could have been done by ADD BX,2 or INC BX INC BX which would mean the MOV CX,2 would be unnecessary - just the way I wrote it...) and increment the '1' in AH to '2'.
The end-condition for the loop is when AH gets incremented from '9' to - well, ':' or '9'+1. If it hasn't reached that end-condition, then run around the loop until all of the values '1'..'9' have been tested. If you haven't got to PNAME yet, then there's an error because the character input wasn't allowed, so point to an error message and then print it.
Now jumping to the end - probably you'd want to terminate the program, so you'd execute
MOV AH,4CH
INT 21H

I can't figure out how to delete a row in my tasm assembly homework

I have a compiled assembly program and I'm asked to modify it by removing the last row seen in the cmd prompt. I'm new at assembly so I can't find a solution.
When you run it 5 rows appear, and I'm trying to delete the row below;
Press [q]uit [e]xecute [c]lear:
;Serhad Ali Turhan 040060390
.8086
.MODEL small
.STACK 256
.DATA
;~~~~~~ Declarations ~~~~~~~~
CR equ 13d
LF equ 10d
cPrompt DB 'Press [q]uit [e]xecute [c]lear: $'
cName DB 'SERHAD ALI TURHAN',CR,LF,'$'
cNum DB 'Electronical Engineering',CR,LF,'$'
cSch DB 'ITU Ayazaga Kampusu 34469 Maslak-ISTANBUL',CR,LF,'$'
vDW DB 0 ;Day of the Week
vMon DB 0 ;Month
vDM DB 0 ;Day of the month
cDW0 DB 'SUNDAY$ ' ;All days are 10 bytes
cDW1 DB 'MONDAY$ '
cDW2 DB 'TUESDAY$ '
cDW3 DB 'WEDNESDAY$'
cDW4 DB 'THURSDAY$ '
cDW5 DB 'FRIDAY$ '
cDW6 DB 'SATURDAY$ '
vI2S_I DW 0 ;2 bytes
vI2S_S DB ?,?,?,?,'$' ;4 bytes
cExcode DB 0
;~~~~~~~~ Main Program ~~~~~~~~
.CODE
MAIN PROC
mov ax,#data ; Initialize DS to address
mov ds,ax ; of data segment
call pClr
jmp pExecute
jmp pMenu ;
;~~~~~ Menu ~~~~~
pMenu:
lea dx,cPrompt ;
call puts ;
call getc ;AL has user selection
push ax ;Store it
call pNL ;
pop ax ;
cmp al,'q' ;al?=q
je lQuit ;Quit
cmp al,'c' ;al?=c
je lClr ;Clear screen
cmp al,'e' ;
je pExecute ;
jmp pMenu ;
lClr:
call pClr
jmp pMenu ;
lQuit:
call pQuit
;~~~~~~~~
pExecute:
call pInfo
call pClock
call pDate
call pNL
jmp pMenu ;
pInfo:
lea dx,cName ;
call puts ;Display Name
lea dx,cNum
call puts ;Display Department
lea dx,cSch
call puts ;Display School Address
ret
pClock:
mov ah,2ch ;get time
int 21h
push dx
push cx
mov al,ch ;ch->hour
call pDisp
mov dl,':'
call putc
pop ax ;cl->minute
call pDisp
mov dl,':'
call putc
pop ax ;dh->seconds
mov al,ah
call pDisp
call pNL
ret
pDate:
mov ah,2ah ;get date
int 21h
mov vDW,al ;Store day of week
mov vMon,dh ;Store month
mov vDM,dl ;Store day of month
mov vI2S_I,cx ;Year will be stored in
call pI2S ;vI2S_s as ASCII
mov al,vDM ;Print day of month
call pDisp
mov dl,'.'
call putc
mov al,vMon ;Print month
call pDisp
mov dl,'.'
call putc
lea dx,vI2S_S ;Print year
call puts
mov dl,'-'
call putc
call pDW ;Print day of week
ret
pDW:
mov al,vDW
mov bl,10 ;All days are 10 bytes
mul bl
mov ah,0
mov bx,ax
lea dx,cDW0[bx]
call puts
ret
pDisp:
xor ah,0 ;
aam
add ax,3030h ;
push ax
mov dl,ah ;
call putc
pop dx
call putc
ret
;vI2S_I=1000*vI2S_S[0]+100*vI2S_S[1]+10*vI2S_S[2]+vI2S_S[3]
pI2S: ;intToStr
mov cx,1000 ;
mov ax,vI2S_I ;
mov dx,0
div cx ;
add al,'0'
mov vI2S_S,al ;
mov cx,100 ;
mov ax,dx
mov dx,0
div cx
add al,'0'
mov vI2S_s[1],al
mov cx,10 ;
mov ax,dx
mov dx,0
div cx
add al,'0'
mov vI2S_s[2],al
add dl,'0'
mov vI2S_s[3],dl ;
ret
;~~~~~~~~ Screen I/O Functions ~~~~~~~~
getc:
mov ah,1h ;read character from keyboard
int 21h ;to al
ret ;
putc:
mov ah,2h ;display character
int 21h ;at dl
ret ;
puts:
mov ah,9h ;display string terminated by '$'
int 21h ;at the adress dx
ret ;
;~~ Clear screen ~~~~
pClr:
mov ax,03h ;
int 10h ;
ret ;
;~~ New Line ~~~~~~~
pNL:
mov dl,CR ;
call putc ;
mov dl,LF ;
call putc ;
ret
;~~~~~~~~~ Exit ~~~~~~~~~~~~~~~
;return to DOS
pQuit:
mov ah,4Ch ; DOS function: Exit program
mov al,cExcode ; Return exit code value
int 21h ; Call DOS. Terminate program
MAIN ENDP
END MAIN ; End of program / entry point
I'll offer some guiding questions:
Does the text that you're looking to prevent appear in the code?
Is it identified in some way?
Does that identifier exist elsewhere in the code?
Where does that usage take you?
There are only a handfull of instructions that you care about. These questions will help you find them, and hopefully understand which one to delete.

Resources