Reputation: 1
I'm trying to do a homework assignment in 8086 assembly. But I can't seem to get it. I know my code is incorrect and I try to seek the right approach and answers (people told me it's completely wrong, like it's not the right path from the start).
I have a problem to find the max number in a vector.
.model small
.stack 100h
.data
a db '5 ', '21 ', '4 ', '13 ', '2 ', '31 ', '22 ', '$' - the vector
max db 0 - max variable
.code
mov ax,@data
mov ds,ax
mov ah, 09h
mov dx, offset a
int 21h
mov si,0 - setting the increment variable to 0
jmp e1
e1:
mov bh,a[si]
mov dh,a[si+1]
cmp bh,dh - compare the 0 element to the 1 element
jl e2
inc si
jmp e1
e2:
mov max,dh - if bh is less than dh, set max to dh value
inc si
cmp si, 6 - starting from 0, compare if the increment variable is at the end
je e3
jmp e1
e3:
mov dx,offset max
mov ah,09h
int 21h
mov ah,4ch
int 21h
end
People told me I should reimagine it, but I don't know how to do that exactly. They said the reason my code doesn't work is because assembly takes the whole thing in apostrophes, including the space. And I should somehow use the ASCII table, which is a pain in the ass.
Upvotes: 0
Views: 1322
Reputation: 16626
It's not clear to me, how using ASCII is pain in the ass, as your Assembler knows the ASCII, so it's doing all the hard work for you.
If it would NOT, you would have to define "Hello world!" like this:
hello_str db 72, 101, 108, 108, 111, 32
db 119, 111, 114, 108, 100, 33, 36
instead of the convenient
hello_str db 'Hello world!$'
You can actually do things like sub al,'0'
, so you don't need to remember the '0'
is value 48
, like I have it imprinted in brain from 8 bit era, because back then I didn't have any assembler, and I had to assembly my code from paper into machine code bytes by hand, and then writing short BASIC program which did set the memory with those hand calculated values. And if I messed up instruction encoding, something completely different did execute and usually it crashed the whole machine. You have no idea, what is PITA, if you think ASCII is. :D
BTW, even your high-level logic in that code is wrong, even if it would work like you wished for in terms of vector values, you would get wrong results, for example:
vector: 2,8,3,5,4,4 would report max value 5
And if you would put vector into separate data segment, and fill it with the same value (65536 x "5" for example), you would end with infinite loop.
Write first your algorithm in comments like this:
; load vector size
; if size is zero, end with "no data" result
; (jump separate branch of code with own exit)
; set temporary_max to first element of vector
; load index to point to second element of vector
; while (index within bounds of vector) do {
; compare vector element at index with temporary_max
; if element is greater, then temporary_max = element
; increment index and loop }
; print temporary_max as result
; exit to DOS
Then try to fill up the core parts with some instructions, like that "compare element" and "index" vs "length", so you can think how your data are stored in memory, what is their structure, what is their bitsize, what is their encoding, and which instructions can be used to manipulate them.
If you have the core parts sort of guessed, check how many registers you need, if you can fit fully into CPU only, or you will need also some local variables or stack memory, and allocate the CPU registers to have fixed function for most of the code (like whole "find max" loop can touch memory only when reading vector element, everything else can fit into registers). Write those allocations to the comments, make notes where you have any register clash and you have to preserve some value by extra means (push/pop or local variable).
Then try to fill up each comment part with real instructions, this time resolving it completely. Feel free to start with only some small part, and verify in debugger step by step, that it works as expected (put for example some fake mov register,test_value
ahead to simulate the state you expect in that part, so you can verify in debugger it works as expected).
After you have all parts filled, and debugged, the program should work. Done.
And final thing... which makes me even regret I did bother to share so much experience and knowledge with you...
How can you FFS write something like "e1:
" in your source.
Are you in hurry to hit the keyboard like 10 more times? But then why do you have suddenly time to post whole question here?
One of the first things you should learn about programming is, that you will READ the source many times more, than WRITE it.
There's no point to take shortcuts during writing source, if they make reading more difficult, that will not save any time to you. Whenever you see there's more clear way to rewrite your source, do it. It may take few minutes more, but if the result is cleaner/shorter/easier to read source, it will pay off later, when you will be reading it (many times, during debugging, etc).
If you think e1:
is good enough, then I have suggestion for you, don't use labels at all, simply write the offsets directly into code, like instead of je e3
you can write je $+4
and now you don't need even to write e3:
in your source. Winning.
Upvotes: 2