Write a procedure which divides a 32-bit number by a 16-bit number. The procedure must be general which is it's defined in one module and can be called from another assembly module.
; REGISTERS : Uses CS, DS, SS, AX, SP, BX, CX
; PROCEDURES: Far Procedure SMART_DIV
DATA_SEG SEGMENT WORD PUBLIC
DIVIDEND DW 2345h, 89AB; Dividend =
; 89AB2345H
DIVISOR DW 5678H; 16-bit divisor
MESSAGE DB 'INVALID DIVIDE', '$'
DATA_SEG ENDS
MORE_DATA SEGMENT WORD
QUOTIENT DW 2 DUP (0)
REMAINDER DW 0
MORE_DATA ENDS
STACK_SEG SEGMENT STACK
DW 100 DUP (0); Stack of 100 words
TOP - STACK LABEL WORD; top of stack pointer
STACK_SEG ENDS
PUBLIC DIVISOR
PROCEDURES SEGMENT PUBLIC ; SMART_DIVis declared as an
EXTRN SMART_DIV: FAR ; external label in procedure
; Segment of type FAR
PROCEDURES ENDS
; declare the code segment as PUBLIC so that it can be merged with other PUBLIC
; Segments
CODE_SEG SEGMENT WORD PUBLIC
ASSUME CS: CODE, DS: DATA_SEG, SS: STACK SEG
START: MOV AX, DATA_SEG; Initialize data segment
MOV DS, AX ; using AX register
MOV AX, STACK_SEG ; Initialize stack segment
MOV SS, AX; using AX register
MOV SP, OFFSET TOP_STACK; Initialize stack pointer
MOV AX, DIVIDEND ; Load low word of
; Dividend
MOV DX DIVIDEND + 2; Load high word of
; Dividend
MOV CX, DIVISOR ; Load divisor
CALL SMART_DIV
; This procedure returns Quotient in the DX: AX pair and Remainder in CX register.
; Carry bit is set if result is invalid.
JNC SAVE_ALL; IF carry = 0, result valid
JMP STOP ; ELSE carry set, don't
; save result
ASSUME DS: MORE_DATA ; Change data segment
SAVE_ALL: PUSH DS ; Save old DS
MOV BX, MORE_DATA ; Load new data segment
MOV DS, BX ; register
MOV QUOTIENT, AX ; Store low word of
; Quotient
MOV QUOTIENT + 2, DX ; Store high word of
; Quotient
MOV REMAINDER, CX ; Store remainder
ASSUME DS: DATA_SEG
POP DS; Restore initial DS
JMP ENDING
STOP: MOV DL, OFFSET MESSAGE
MOV AX, AH 09H
INT 21H
ENDING: NOP
CODE_SEG ENDS
END START