kingcobra1986
kingcobra1986

Reputation: 971

Comparing hexadecimal integers in 8086 Assembly Language not working

I'm trying to write an 8086 program that compares an array of integers that are written in hexadecimal. I know that the highest number is 0xFF but it doesn't result in that being the max value. (also I'm not sure if I ended the program correctly. Here is my code:

DATA SEGMENT    ;declares the data segment  

SIZEA   DW 10  
MAXV    DW 0  
INTARR  DW 0x1,0x2,0x4,0xFF,0xFE,0xFA,0x7,0x9,0x8,0xFD  

DATA ENDS       ;ends the data segment

CODE SEGMENT    ;declares the code segment
START:          ;declares start label

        MOV AX,DATA         ;moves the data to the AX register
        MOV DS,AX           ;moves the date from the AX reg to DS

        LEA SI,INTARR       ;loads the address of INTARR to SI

        MOV BX,INTARR[SI]   ;loads the first array item into BX
        MOV CX, SIZEA       ;loads the size of the array to CX
        MOV DX, MAXV        ;loads the maxv variable to DX

THELOOP:        ;This is where the loop starts
        MOV BX,INTARR[SI]   ;loads the array item at index SI
        CMP MAXV,BX         ;compares BX to the value of MAXV                                          
        JGE SKIP            ;goes to SKIP if MAXV is greater
        MOV MAXV,BX         ;if BX is greater BX moves to DX

SKIP:           ;this is the skip label
        INC SI              ;increments SI for the next loop
        LOOP THELOOP        ;loops

CODE ENDS       ;ends the segment
END START       ;ends start label

 ret

I'm using emu8086. When I emulate it, and watch the variables, it states that the MAXV is 0900h. And it runs through about 20 NOP commands. Any help would be greatly appreciated!

Upvotes: 0

Views: 1662

Answers (1)

Maximilian Schier
Maximilian Schier

Reputation: 1679

Ok here are all the issues I see with your code:

  1. SIZEA and MAXV are addresses. So when you write MOV CX,SIZEA you dont load the content of SIZEA but its address. Which is not what you want. You wanna write MOV CX,[SIZEA]
  2. I am not sure how emu8086 works since I never used it. However the way you set up your data segment looks kind of suspicious. Aren't you loading an offset address into a segment register?
  3. The ret is part of your function and should be in your code segment. However I do not know if there is any valid code to return to.
  4. The first lea instruction is not doing what you want it to do, just remove it
  5. The first MOV BX,INTARR[SI] is redundant and can be removed.
  6. You only increase SI by one byte, however the lenght of an array entry is a word (2-bytes)

Here is what I changed to get your code working. Note that this is not for emu8086 but standard NASM though:

START:  XOR AX,AX       ; Clear data segment, may not be how you do it on emu8086
        MOV DS,AX       
        MOV SI,AX       ; Clear the Source index        
        MOV CX,[SIZEA]
        XOR DX,DX       ; Note how I just clear DX, no need to load 0 from memory
                        ; DX will then contain highest value    
THELOOP:MOV BX,[INTARR+SI] ; I am just using this syntax because it is the standard for NASM
        CMP DX,BX       ; Compare max value with current value
        JGE SKIP
        MOV DX,BX       ; Now just move the max value to the register
SKIP:   ADD SI,2        ; Move by 2 bytes since it is a word array
        LOOP THELOOP    ;
        MOV [MAXV],DX   ; Now you can save the highest value to memory
                        ; less memory access so faster execution
        RET

; DATA
SIZEA   DW      10
MAXV    DW      0
INTARR  DW      0x1,0x2,0x4,0xFF,0xFE,0xFA,0x7,0x9,0x8,0xFD

Upvotes: 2

Related Questions