Topliner
Topliner

Reputation: 1

Print the maximum number from the following vector in Assembly 8086

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

Answers (1)

Ped7g
Ped7g

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

Related Questions