0

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.

zx485
  • 28,498
  • 28
  • 50
  • 59
Topliner
  • 1
  • 3
  • 3
    What they wanted to tell you is that you have strings, not numbers. Either declare them to be numbers or convert them. – Jester Jan 14 '17 at 19:16
  • Switch your assembler to produce a listing for you, then study how the vector is defined in memory (byte values). Or even better, load it into debugger, and watch registers + memory there. Then you will have maybe question, why "5" is `0x35`, so you will have to read something about ASCII encoding. Then you will change your vector definition, and you will be like 'but how can I print number?" And the signpost at http://stackoverflow.com/tags/x86/info will suggest you to check http://stackoverflow.com/a/40505938/4271923 (maybe check the whole question for inspiration), etc. – Ped7g Jan 14 '17 at 20:48
  • 1
    BTW, if this is homework assignment, then there was some course/lessons before it. Your code makes me wonder what did they teach you (I'm not just making fun of it, if you will take a time to write short factual summary, I will really appreciate it, I'm always interested to learn how some things are being taught, especially if I have some strong opinion what I think is correct way). – Ped7g Jan 14 '17 at 20:51

1 Answers1

2

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.

Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • @Topliner: You generalize and assume something about many, instead of understanding I'm a single individual. Your Q did show lack of basic effort, which you show just further. "teacher writing on table" is not a programmer writing source, and he can save some amount time there, still they were not capable to explain what symbols in Assembly are and how important they can be. At least you put reasonable comments there. Anyway, I see you mind the form of the answer, no question about content, so all is clear I suppose. Glad I could help. BTW, you will have maybe hard time with universe then... – Ped7g Jan 15 '17 at 11:52
  • @Topliner: You can of course also wait until somebody nice will take your hand and get you all the way along, or even do to the homework for you. There are certainly some very nice and clever people here. Or you may learn to extract factual information from answers done by bitter toxic existences like me, eventually learning more than you bargained for. It's a free world, you have so many choices and only sky is your limit. For example the argument "we were not taught about debugger" is yourself imposing limit on yourself, expecting everything will be taught to you. Nope. Push on your own too. – Ped7g Jan 15 '17 at 12:07
  • You get a long, detailed, helpful answer, and you rant in the comments that Stack Overflow is full of assholes. Do you have a mirror hanging on your wall, @topliner? Ped7g, I'm surprised one of your first coding projects wasn't writing an assembler. :-) – Cody Gray - on strike Jan 15 '17 at 17:43
  • @CodyGray I was not that clever/good, took me years to pick up some things on theoretical level. It was easy for me to think in instructions and do something nice with video memory,... but the whole math theory was missing (I was like 12-15, ahead of uni), also back then I had ratio about 1h of lecturing vs 20+h DIY, web was ~1y old (ie irrelevant) and no good books (post communism) => just going by instruction reference, hints + RE/experiments. Basically I didn't know there's such thing as Assembler, and I didn't get idea. ;) Then finally somebody gave me one good (MRS). I'm asshole BTW, np:) – Ped7g Jan 15 '17 at 18:03
  • @CodyGray plus the main reason probably.. I didn't have actual HW for first like ~6 years, so I didn't want waste my machine time (few hours here and there either by breaking some access rules at uni labs (as high school, "stealing" time from uni), or at home of friends who had some home computer) by doing some assembler, I had lot of time to prepare the machine code at home at paper, or when I had a luxury of machine with compiler, I did bring source on paper and typed it in. Usually there was not enough time to fully debug it, so I had to have exact paper copy to debug at home in spare time. – Ped7g Jan 15 '17 at 18:11
  • 2
    I haven't actually upvoted this because the bottom half was confrontational, condescending and looking to pick a fight. I'm not surprised Topliner actually went off on you because you did spew on him in the answer. Maybe consider removing the first 3 sentences of the second half below the horizontal line and the last paragraph can be reworded to simply suggest using more useful label names. They add nothing to the answer except to come across as condescending. The OP is correct about how responses like this don't make it inviting to ask a question. – Michael Petch Jan 16 '17 at 03:33