*******************************************************************************
*******************************************************************************
**** PROGRAMING GROUP: VINEY KHARBANDA
****
****
****
**** SOFTWARE PROJECT
**** MICROPROCESSOR EE 3310, SPRING 1999, DR. PFEIFER
**** ALGORITHM: TAKES A STRING FROM C AND CONVERTS
**** ASCI CHARATCERS OBTAINED FROM STACK
**** TO BINARY, THAN DIVISION IS USED
**** TO FIND ROMAN NUMERAL BY FINDING THE
**** QUOTIENT AND REMAINDER WHERE QUOTIENT
**** IS USED TO DISPLAY PARTICULAR CHARCTER
**** THAT NUMBER OF TIME AND REMAINDER IS
**** USED TO CHECK WHEN TO STOP ROMAN CONVERSION
**** AND END PROGRAM.
**** DATE CREATED: MARCH 15, 1999
**** ASSEMBLY FILE NAME: A2R.ASM
**** LINK WITH : TC30
*******************************************************************************
*******************************************************************************
PUBLIC _A2R
.MODEL LARGE
.CODE
DATA_SEG SEGMENT
REMA DW ?
DATA_SEG ENDS
_A2R PROC FAR
ASSUME ES:DATA_SEG
PUSH BP ; Save BP
MOV BP,SP ; use stack pointer to locate string
LES BX,[BP+6] ; load BX with offset to locate string
MOV AX,0 ; clear AX
MOV CX,0 ; clear CX
MOV DX,0 ; clear DX
MOV AL,ES:[BX] ; AL gets first ASCI character
SUB AL,30H ; strip off the 3 from ASCI character
BACK: INC BX ; increment BX to get next ASCI character
MOV CX,0 ; clear CX
MOV CL,ES:[BX] ; load CL with second ASCI character
CMP CL, 00H ; compare it with NULL--END OF STRING?
JZ BEGIN ; if end of string start converting
SUB CL,30H ; else strip off the 3 from ASCI character
PUSH BX ; save BX
MOV BX,0H ; clear BX
MOV BL,0AH ; move 10 to BX to multiply
MUL BX ; mulitply AX with BX and result in AX
POP BX ; reload previous BX to get next character
ADD AX,CX ; ADD and store number in AX
JMP BACK ; jump back to get next character
BEGIN: CMP AX,1 ; is number 1?
JA NEXT2 ; jump to NEXT2 if number is greater than 1
PRE1: MOV DX,0 ; else if equal to 0
MOV BX,1 ; used to divide
DIV BX ; DIVIDE AX BY BX WHERE BX IS 1
MOV CX,AX ; MOV QUOTIENT IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
BACK1: MOV AH,2H ; display charcter
MOV DL,'I' ;
INT 21H ;
LOOP BACK1 ;
MOV AX,BX ; move BX to AX for future converisons
CMP BX,0 ; check to see if remainder is 0
JZ END1 ; if remainder is zero than end
JNZ BEGIN ; else continue converting
NEXT2: CMP AX,2 ; compare number with 2
JA NEXT3 ; check if number greater than 2
JB PRE1 ; check if number less than 2-- not needed
PRE2: MOV DX,0 ; clear DX for division
MOV BX,2 ; move divisor in BX to divide
DIV BX ; DIVIDE AX BY BX WHERE BX IS 2
MOV CX,2 ; MOV 2 IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
BACK2: MOV AH,2H ; display character to screen
MOV DL,'I' ;
INT 21H ;
LOOP BACK2 ; display 'II' since CX is 2
MOV AX,BX ; save remainder for future conversions
CMP BX,0 ; check if remainder is zero
JZ END1 ; if remainder is zero than end
JNZ BEGIN ; else start converting from beginning
NEXT3: CMP AX,3 ; compare number with 3
JA NEXT4 ; if number gretaer than 3 than compare with 4
JB PRE2 ; else if less than 3 than compare with 2
PRE3: MOV DX,0 ; clear DX for division
MOV BX,3 ; move divisor in BX
DIV BX ; DIVIDE AX BY BX WHERE BX IS 3
MOV CX,3 ; MOV 3 IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
BACK3: MOV AH,2H ; display character
MOV DL,'I' ;
INT 21H ;
LOOP BACK3 ; displays 'III' since CX is 3
MOV AX,BX ; save remainder for future converisons
CMP BX,0 ; check if remainder is 0
JZ END1 ; if remainder 0 than finish
JNZ BEGIN ; else continue converison from beginning
NEXT4: CMP AX,4 ; compare number with 4
JA NEXT5 ; if number greater than 4 than compare with 5
JB PRE3 ; if less than 4 than compare with 4
PRE4: MOV DX,0 ; clear for divison purposes
MOV BX,4 ; move divisor 4 in BX
DIV BX ; DIVIDE AX BY BX WHERE BX IS 4
MOV CX,0 ; MOV quotient IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
MOV AH,2H ;
MOV DL,'I' ;
INT 21H ; displays 'I'
MOV AH,2H
MOV DL,'V' ; displays 'V'
INT 21H
MOV AX,BX
CMP BX,0
JZ END1
JNZ BEGIN
NEXT5: CMP AX,5
JA NEXT9
JB PRE4
PRE5: MOV DX,0
MOV BX,5
DIV BX ; DIVIDE AX BY BX WHERE BX IS 2
MOV CX,AX ; MOV QUOTIENT IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
BACK5: MOV AH,2H
MOV DL,'V'
INT 21H
LOOP BACK5
MOV AX,BX
CMP BX,0
JZ END1
JNZ BEGIN
NEXT9: CMP AX,9
JA NEXT10
JB PRE5
PRE9: MOV DX,0
MOV BX,9
DIV BX ; DIVIDE AX BY BX WHERE BX IS 2
MOV CX,0 ; MOV QUOTIENT IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
MOV AH,2H
MOV DL,'I'
INT 21H
MOV AH,2H
MOV DL,'X'
INT 21H
MOV AX,BX
CMP BX,0
JZ END1
JNZ BEGIN
NEXT10: CMP AX,10
JA NEXT40
JB PRE9
PRE10: MOV BX,10
MOV DX,0
DIV BX
MOV BX,DX ; SAVE REMAINDER IN BX\
MOV CX,AX ; SAVE QUOTIENT IN AX
BACK10: MOV AH,2 ; USED TO DISPLAY
MOV DL,'X' ; USED TO DISPLAY
INT 21H ; USED TO DISPLAY
LOOP BACK10 ; LOOP BACK TO DISPLAY X'S
MOV AX,BX ; MOVE REMAINDER BACK TO AX
CMP BX,0 ; COMPARE REMAINDER WITH 0
JZ END1 ; IF REMAINDER 0 THEN END
JNZ BEGIN ; ELSE START AGAIN TO COMPARE WITH 2
NEXT40: CMP AX,40
JA NEXT50
JB PRE10
PRE40: MOV DX,0
MOV BX,40
DIV BX ; DIVIDE AX BY BX WHERE BX IS 2
MOV CX,AX ; MOV QUOTIENT IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
MOV AH,2H ;
MOV DL,'X' ;
INT 21H ;
MOV AH,2H ;
MOV DL,'L' ;
INT 21H ;
MOV AX,BX ; move remainder in AX for future conversion
CMP BX,0 ; check if remainder is 0 ?
JZ END1 ; if remainder 0 than end
JNZ BEGIN ; else cintinue conversion from beginning
NEXT50: CMP AX,50 ; compare number with 50 ?
JA NEXT90 ; if greater than compare with 50
JB PRE40 ; else if less than execute division by 40
PRE50: MOV BX,50 ; move divisor in BX
MOV DX,0 ; clear DX for division
DIV BX ; divide AX by BX
MOV BX,DX ; SAVE REMAINDER IN BX
MOV CX,AX ; SAVE QUOTIENT IN AX
MOV AH,2 ; USED TO DISPLAY
MOV DL,'C' ; USED TO DISPLAY
INT 21H ; USED TO DISPLAY
MOV AX,BX ; MOVE REMAINDER BACK TO AX
CMP BX,0 ; COMPARE REMAINDER WITH 0
JZ END1 ; IF REMAINDER 0 THEN END
JNZ BEGIN ; ELSE START AGAIN TO COMPARE WITH 2
NEXT90: CMP AX,90 ; compare number with 90 ?
JA NEXT100 ; if greater than compare with 90
JB PRE50 ; else if less than execute division by 50
PRE90: MOV BX,90 ; move divisor in BX
MOV DX,0 ; clear DX for divison
DIV BX ; divide AX with BX
MOV BX,DX ; SAVE REMAINDER IN BX
MOV CX,AX ; SAVE QUOTIENT IN AX
MOV AH,2 ; USED TO DISPLAY
MOV DL,'X' ; USED TO DISPLAY
INT 21H ; displays 'X'
MOV AH,2 ; USED TO DISPLAY
MOV DL,'C' ; USED TO DISPLAY
INT 21H ; displays 'C'
MOV AX,BX ;MOVE REMAINDER BACK TO AX
CMP BX,0 ;COMPARE REMAINDER WITH 0
JZ END1 ;IF REMAINDER 0 THEN END
JNZ BEGIN ;ELSE START AGAIN TO COMPARE WITH 2
NEXT100: CMP AX,100 ; compare number with 100
JA NEXT400 ; if greater than compare with 400
JB PRE90 ; else if less than execute division by 90
PRE100: MOV BX,100 ; move divisor in BX
MOV DX,0 ; clear DX for divison
DIV BX ; divide AX by BX
MOV BX,DX ; SAVE REMAINDER IN BX
MOV CX,AX ; SAVE QUOTIENT IN AX
BACK100: MOV AH,2 ; USED TO DISPLAY
MOV DL,'C' ; USED TO DISPLAY
INT 21H ; USED TO DISPLAY
LOOP BACK100 ; LOOP BACK TO DISPLAY C'S
MOV AX,BX ; MOVE REMAINDER BACK TO AX
CMP BX,0 ; COMPARE REMAINDER WITH 0
JZ END1 ; IF REMAINDER 0 THEN END
JNZ BEGIN ; ELSE START AGAIN TO COMPARE WITH 2
NEXT400: CMP AX,400 ; compare number with 400
JA NEXT500 ; if greater than compare with 500
JB PRE100 ; if less than execute division by 100
PRE400: MOV DX,0 ; clear DX for divison purpose
MOV BX,400 ; move divisor in BX
DIV BX ; DIVIDE AX BY BX WHERE BX IS 400
MOV CX,AX ; MOV QUOTIENT IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
MOV AH,2H
MOV DL,'C'
INT 21H ; displays 'C'
MOV AH,2H ;
MOV DL,'D' ;
INT 21H ; displays 'D'
MOV AX,BX ; move remainder in AX for future conversion
CMP BX,0 ; compare remainder with 0
JZ END1 ; if remainder is 0, than end
JNZ BEGIN ; else continue conversion from beginning
NEXT500: CMP AX,500 ; compare number with 500
JA NEXT900 ; if greater compare with 900
JB PRE400 ; else if less than execute divison by 400
PRE500: MOV BX,500 ; move divisor in BX
MOV DX,0 ; clear DX for division
DIV BX ;divide AX by BX--divisor
MOV BX,DX ;SAVE REMAINDER IN BX
MOV CX,AX ;SAVE QUOTIENT IN AX
MOV AH,2 ; USED TO DISPLAY
MOV DL,'D' ; USED TO DISPLAY
INT 21H ;USED TO DISPLAY
MOV AX,BX ;MOVE REMAINDER BACK TO AX
CMP BX,0 ;COMPARE REMAINDER WITH 0
JZ END1 ;IF REMAINDER 0 THEN END
JNZ BEGIN ;ELSE START AGAIN TO COMPARE WITH 2
NEXT900: CMP AX,900 ; compare number with 900
JA NEXT1000 ; if greater than 900, compare with 1000
JB PRE500 ; if less than execute division with 500
PRE900: MOV DX,0 ; clear DX for division
MOV BX,900 ; move divisor in BX
DIV BX ; DIVIDE AX BY BX WHERE BX IS 900
MOV CX,AX ; MOV QUOTIENT IN CX TO LOOP
MOV BX,DX ; MOV REMAINDER IN BX
MOV AH,2H ;
MOV DL,'C' ;
INT 21H ; displays 'C'
MOV AH,2H ;
MOV DL,'M' ;
INT 21H ; displays 'M'
MOV AX,BX ; move remainder in AX for future conversion
CMP BX,0 ; check if remainder is 0?
JZ END1 ; if remainder is 0 than end
JNZ BEGIN ; else cintinue conversion form beginning
NEXT1000: CMP AX,1000 ; compare number with 1000
JB PRE900 ; if less than 1000 than compare with 900
PRE1000: MOV BX,1000 ; move divisor in BX
MOV DX,0 ; clear DX for division
DIV BX ; divide AX by DX
MOV BX,DX ;SAVE REMAINDER IN BX
MOV CX,AX ;SAVE QUOTIENT IN AX
BACK1000: MOV AH,2 ; USED TO DISPLAY
MOV DL,'M' ; USED TO DISPLAY
INT 21H ;USED TO DISPLAY
LOOP BACK1000 ;LOOP BACK TO DISPLAY X'S
MOV AX,BX ;MOVE REMAINDER BACK TO AX for future conversip
CMP BX,0 ;COMPARE REMAINDER WITH 0
JZ END1 ;IF REMAINDER 0 THEN END
JNZ BEGIN ;ELSE continue conversion from beginning
END1: MOV AH,4CH
INT 21H
POP BP
RET 4
_A2R ENDP
END