Write an ALP to find the LCM of two 16bit numbers

 


install emu 8086 in pc for compiling this code


ASSEMBLY CODE:

MOV BX, 1100h  ;Set BX register as pointer for data Set DI register as pointer for result

MOV DI, 1200h;set DI register as pointer for result

 MOV AX, [BX];Get the First Data in AX register

     MOV CX, [BX+2]          ; Get the Second Data in CX register

 CALL GCD;Call Procudure GCD

 MOV AX, [BX];Get the Second Data in BX register

MOV CX, [BX+2];Get the Product of Two numbers in AX and DX Divide the Product to GCD

 MUL CX

 DIV SI

MOV [DI],AX

 HLT

GCD PROC NEAR

RPT:

CMP AX, CX

  ;Compare the two data If the data are equal

JE SAVE

; If AX is greater than XCHG AX,CX

;If AX is Less than CX, then exchange AX and CX CX then Go to SKIP

;store CX as GCD

JNC SKIP

XCHG AX,CX

SKIP:

MOV DX,0000h

DIV CX

;Divide the two data

 CMP DX,0000h; Check Whether remainder is zero

JE SAVE

MOV AX, DX

 JMP RPT

 ;If remainder is zero, then store CX as GCD

;If remmainder is not zero, move remainder to AX Repeat comparsion and divison

SAVE:

MOV SI,CX ; Store CX as GCD

RET

GCD ENDP





 next emulate the code and open view section. Tab on memory location change  0000: 0000  into 0000:1100 and memory  00 19  00 4b 00  00 as this



 


next tap single step 


explanation of the code:

I'd be glad to explain the assembly code for calculating the LCM (Least Common Multiple) of two 16-bit data values:

Data Segment:

  • MOV BX, 1100h: This line sets the BX register to point to the memory location where the first 16-bit data value is stored. The value 1100h is the offset address in hexadecimal format (1100 in hexadecimal is 4352 in decimal).
  • MOV DI, 1200h: This line sets the DI register to point to the memory location where the final result (LCM) will be stored. Similar to BX, 1200h is the offset address for the result (4608 in decimal).

Main Program:

  1. Load Data:

    • MOV AX, [BX]: This instruction retrieves the first 16-bit data value from the memory location pointed to by BX and stores it in the AX register.
    • MOV CX, [BX+2]: This instruction retrieves the second 16-bit data value from the memory location 2 bytes after the address pointed to by BX (accounting for 16-bit data size) and stores it in the CX register.
  2. Calculate GCD (Greatest Common Divisor):

    • CALL GCD: This line calls the GCD procedure, which is responsible for calculating the GCD of the values in AX and CX. The registers' contents are automatically pushed onto the stack before the call.
  3. Get Product for LCM:

    • After the GCD procedure returns, the GCD is assumed to be in CX.
    • MOV AX, [BX]: This line again retrieves the first data value because we need it for calculating the LCM.
    • MOV CX, [BX+2]: This line retrieves the second data value (just to be safe, as the GCD procedure might have modified CX).
  4. Calculate LCM:

    • MUL CX: This instruction multiplies the values in AX and CX, storing the 32-bit product in the AX:DX registers. AX holds the most significant 16 bits of the product, and DX holds the least significant 16 bits.
    • DIV SI: This instruction divides the 32-bit product (AX:DX) by the GCD value in the SI register (which was previously loaded with the GCD from the GCD procedure). The result (LCM) is stored in AX, and the remainder (which should be 0) is discarded.
  5. Store Result:

    • MOV [DI], AX: This instruction stores the final LCM value from the AX register into the memory location pointed to by DI (the result address).
  6. Halt:

    • HLT: This instruction halts the program's execution.

GCD Procedure (GCD PROC NEAR):

This procedure implements the Euclidean algorithm to find the GCD of the values in AX and CX:

  1. Loop:

    • RPT: This instruction starts a repeat loop. Without an explicit count, the loop continues until the RET instruction is encountered.
    • CMP AX, CX: This instruction compares the values in AX and CX.
    • JE SAVE: If the values are equal (Jump if Equal), the GCD is found, and the code jumps to the SAVE label to store the GCD.
  2. Exchange Values:

    • If the values are not equal:
      • JNC SKIP: Jump if Not Carry (meaning no overflow occurred during comparison). This condition is true if AX is greater than CX. If so, the code jumps to the SKIP label to swap the values.
      • XCHG AX, CX: This instruction exchanges the values in AX and CX if AX is less than CX.
  3. Division:

    • SKIP:: This label marks the point where either AX is greater than CX or they have been swapped.
    • MOV DX, 0000h: This instruction initializes the DX register (which will hold the remainder during division) to zero.
    • DIV CX: This instruction divides the value in AX by the value in CX, storing the quotient in AX and the remainder in DX.
  4. Check Remainder:

    • CMP DX, 0000h: This instruction compares the remainder in DX with zero.
    • JE SAVE: If the remainder is zero (meaning the GCD has been found), the code jumps to the SAVE label to store the GCD.
  5. Continue Looping:

    • `MOV AX

The missing line in the GCD procedure should be:

Code snippet
MOV AX, DX  ; Move the remainder (DX) to AX for the next iteration

Here's why:

  1. Initial Division:

    • After the initial division (DIV CX), the quotient is stored in AX, and the remainder is stored in DX.
  2. Check Remainder:

    • The CMP DX, 0000h instruction checks if the remainder is zero. If it is, the GCD has been found.
  3. Iterative Division:

    • However, if the remainder is not zero, we need to continue the Euclidean algorithm using the remainder as the new divisor and the previous divisor (CX) as the dividend for the next iteration.
  4. Moving Remainder:

    • The missing line MOV AX, DX moves the remainder from DX to AX. This ensures that AX holds the remainder for the next division in the loop (DIV CX).
    • By contrast, if we didn't have this line, AX would still hold the quotient from the previous division, leading to incorrect calculations in the next iteration.

Here's the revised GCD procedure with the missing line added:

Code snippet
GCD PROC NEAR

RPT:
  CMP AX, CX
  JE SAVE  ; If equal, GCD found

  JNC SKIP  ; Jump if AX > CX (no carry)
  XCHG AX, CX  ; Swap if AX < CX

SKIP:
  MOV DX, 0000h  ; Initialize remainder (DX) to zero
  DIV CX

  CMP DX, 0000h  ; Check if remainder is zero
  JE SAVE  ; If zero, GCD found

MOV AX, DX  ; **Move remainder to AX for next iteration**
JMP RPT

SAVE:
  MOV SI, CX  ; Store GCD in SI (previously loaded into DI)
  RET
GCD ENDP

With this modification, the GCD procedure correctly implements the Euclidean algorithm to find the GCD of the two values in AX and CX. The GCD is then used to calculate the LCM in the main program.


For better understand

Post a Comment

0 Comments