0

I am kind of new to 8086 programming, and it is a part of my subjects this semester. I find it a bit difficult but kinda still manage. We were asked to do a GCD program and here is what I have done, but I dont get the right answer, any input or suggestions to sharpen my knowledge would be really helpful.

;  Read a pair of 16bit numbers and compute their GCD.
.DATA
   N1 DW ?
   N2 DW ?
   A  DW ?

MSG1 DB 10,13, "ENTER 1ST 16 BIT HEXA NUMBER: $"
MSG2 DB 10,13, "ENTER 2ND 16 BIT HEXA NUMBER: $"
MSG3 DB 10,13, "GCD : $"



.CODE
START:
MOV AX, @DATA
MOV DS, AX 

MOV AH, 09H
LEA DX, MSG1
INT 21H  

LEA SI, N1
CALL READHEXA
MOV [SI+1], AL
CALL READHEXA
MOV [SI], AL
  

MOV AH, 09H
LEA DX, MSG2
INT 21H  

LEA SI, N2
CALL READHEXA
MOV [SI+1], AL
CALL READHEXA
MOV [SI], AL

MOV BX, N1
MOV AX, N2



   

; gcd start

   MAIN: CMP BX, AX
  JNE GCD

MOV AH, 09H
LEA DX, MSG3
INT 21H   

MOV AX, BX


LEA SI, AX
INC SI
CALL DISPHEXA
DEC SI
CALL DISPHEXA

MOV AH, 4CH
INT 21H

GCD: CMP BX,AX
 JC C1
 SUB BX,AX 
 
 JMP MAIN
C1:  SUB AX,BX
 DAS
 
 JMP MAIN
   



PROC READHEXA
PUSH CX ; GOOD PROGRAMMING ETIQUTTE

MOV AH, 01H ; INTERRUPT TO INPUT CHAR, INPUT IS IN AL
INT 21H             

SUB AL, 30H
CMP AL, 09H
JLE G1 ; IF HIGHER NIBBLE IS BETWEEN O TO 9 IT GOES TO G1
SUB AL, 07H

G1: MOV CL, 04H
    ROL AL, CL
    MOV CH, AL
    
MOV AH, 01H ; INTERRUPT TO INPUT CHAR, INPUT IS IN AL
INT 21H             

SUB AL, 30H
CMP AL, 09H
JLE G2 ; IF HIGHER NIBBLE IS BETWEEN O TO 9 IT GOES TO G1
SUB AL, 07H

G2: ADD AL,CH

POP CX

RET
   ENDP READHEXA  





DISPHEXA PROC NEAR
        
        MOV DL,[SI]   ;FIRST DIGIT
            
        MOV CL,04H
        SHR DL,CL
            
        CMP DL,09H
        JBE L1
        ADD DL,07H
                   
        L1: ADD DL,30H
            MOV AH,02H
            INT 21H
            
        
            
        MOV DL,[SI] ; SECOND DIGIT
        AND DL,0FH
            
        CMP DL,09H
        JBE L2
        ADD DL,07H
            
        L2: ADD DL,30H
            MOV AH,02H
            INT 21H 
            
            RET  ;RETURNS => MAIN PROGRAM
 ENDP  DISPHEXA 
  
    END START
Chris M
  • 33
  • 7
  • 2
    Please add examples of input, actual output, expected output. – 500 - Internal Server Error May 05 '21 at 15:15
  • This is nowhere near minimal as far as a [mcve]. For that, you could simplify to starting with 2 numbers in registers from `mov ax, 123` / `mov cx, 456` or whatever, instead of all that input stuff. If you've separately tested the output stuff, then say so, although possibly good to keep it in a [mcve] so people could copy/paste and not need to use a debugger to see a final value in a register. – Peter Cordes May 05 '21 at 15:20
  • 1
    You are doing `DAS` after `SUB AX,BX`, but not after `SUB BX,AX`. And `LEA SI,AX` seems like nonsense. Did you mean `LEA SI,A`? – Ruud Helderman May 05 '21 at 15:24
  • @500-InternalServerError Jus take any 2 input like 5 and 15 and get the GCD 5, I get the right answer in the register but white displaying the value it shows 0A00 – Chris M May 05 '21 at 16:01
  • @PeterCordes I apologize for that, I will bare this in mind. – Chris M May 05 '21 at 16:02
  • @RuudHelderman I am sorry my code seems vague but I am trying different ways to make things work. – Chris M May 05 '21 at 16:03
  • 1
    You're saying the input and GCD part work, so the bug must be in the hex output, or the way you're passing a number to it. There are lots of working examples of hex output, like [Printing hex values in x86 assembly](https://stackoverflow.com/q/18879672), or [Making the program simpler in assembly (binary to gray, and hex printing)](https://stackoverflow.com/q/67400133) or [Converting bin to hex in assembly](https://stackoverflow.com/q/40818086) for 16-bit. (Or [How to convert a binary integer number to a hex string?](https://stackoverflow.com/a/53823757) for 32-bit mode.) – Peter Cordes May 05 '21 at 16:11
  • 1
    But your `DISPHEXA` looks reasonable (2 cmp/add/add ops on the nibbles); use a debugger to see what's happening with it. – Peter Cordes May 05 '21 at 16:13
  • @ChrisM Your code at `MAIN:` looks weird. Perhaps you expect the result of GCD (whatever it is) to sit in the memory variable `A` but you didn't store it there. – vitsoft May 05 '21 at 18:30
  • @vitsoft it is a bit weird, please consider that I am beginner here, What i have noted is when the AL goes to represent the the second number of the nibble i end up getting an error. – Chris M May 05 '21 at 19:36

1 Answers1

2

I appreciate that you decomposed the program to smaller parts - procedures. A GOOD PROGRAMMING ETIQUTTE however, is to complete each procedure with comments: what it does, what it expects on input, what is its output, which registers it changes. For instance:

PROC READHEXA ; reads two characters from keyboard. If they both are hexa digits 0..9 or A..F, it returns the corresponding value in AL.

PROC DISPHEXA ; displays the contents of a byte in memory addressed by DS:SI as two hexadecimal digits. Registers AX,CX,DX are clobbered.

PROC GCD ; (yet to be written) Calculates GCD of two WORD numbers in memory variables N1, N2 and stores the result in memory variable A.

It is then easier to debug. You should find out that when the calculation is finished at MAIN: CMP BX, AX and both registers are equal, you forgot to store the result from AX into memory variable A. Or change the contract of PROC GCD and let it return the result in AX.

ecm
  • 2,583
  • 4
  • 21
  • 29
vitsoft
  • 5,515
  • 1
  • 18
  • 31