; input8 bit binary number and print out decimal to screen. ; zeros and ones -> decimal value ORG 100h ; macro ; this macro prints a char in AL and advances ; the current cursor position: PUTC MACRO char PUSH AX MOV AL, char MOV AH, 0Eh INT 10h POP AX ENDM .data ; null terminated input string: DB "0" s1 DB "00000000", 0 sum DW 0 ; result. flag DB 0 .code CALL print DB 0dh, 0ah, "8 bit binary: ", 0 ; get string: MOV DX, 9 ; buffer size (1+ for zero terminator). LEA DI, s1 CALL GET_STRING ; check that we really got 8 zeros and ones MOV CX, 8 MOV SI, OFFSET s1 check_s: CMP [SI], 0 JNE ok0 MOV flag, 1 ; terminated. JMP convert ok0: CMP [SI], 'b' JNE ok1 MOV flag, 1 ; terminated. JMP convert ok1: ; wrong digit? Not 1/0? CMP [SI], 31h JNA ok2 JMP error_not_valid ok2: INC SI LOOP check_s ; start the conversion from string to value in SUM variable. convert: MOV BL, 1 ; multiplier. MOV CX, SI SUB CX, OFFSET s1 DEC SI JCXZ stop_program next_digit: MOV AL, [SI] ; get digit. SUB AL, 30h MUL BL ; no change to AX. ADD SUM, AX SHL BL, 1 DEC SI ; go to previous digit. LOOP next_digit ; done! converted number is in SUM. ; check if signed TEST sum, 0000_0000_1000_0000b JNZ print_signed_unsigned print_unsigned: CALL print DB 0dh, 0ah, "decimal: ", 0 MOV AX, SUM CALL PRINT_NUM_UNS JMP stop_program print_signed_unsigned: CALL print DB 0dh, 0ah, "unsigned decimal: ", 0 ; print out unsigned: MOV AX, SUM CALL PRINT_NUM_UNS CALL print DB 0dh, 0ah, "signed decimal: ", 0 ; print out singed: MOV AX, SUM CBW ; convert byte into word. CALL PRINT_NUM JMP stop_program error_not_valid: CALL print DB 0dh, 0ah, "error: only zeros and ones are allowed!", 0 stop_program: ; wait for any key.... CALL print DB 0dh, 0ah, "press any key...", 0 MOV AH, 0 INT 16h RET ; procedures ; copied from c:\emu8086\emu8086.inc GET_STRING PROC NEAR PUSH AX PUSH CX PUSH DI PUSH DX MOV CX, 0 ; char counter. CMP DX, 1 ; buffer too small? JBE empty_buffer ; DEC DX ; reserve space for last zero. ;============================ ; loop to get and processes key presses: wait_for_key: MOV AH, 0 ; get pressed key. INT 16h CMP AL, 13 ; 'RETURN' pressed? JZ exit CMP AL, 8 ; 'BACKSPACE' pressed? JNE add_to_buffer JCXZ wait_for_key ; nothing to remove! DEC CX DEC DI PUTC 8 ; backspace. PUTC ' ' ; clear position. PUTC 8 ; backspace again. JMP wait_for_key add_to_buffer: CMP CX, DX ; buffer is full? JAE wait_for_key ; if so wait for 'BACKSPACE' or 'RETURN'... MOV [DI], AL INC DI INC CX ; print the key: MOV AH, 0Eh INT 10h JMP wait_for_key ;============================ exit: ; terminate by null: MOV [DI], 0 empty_buffer: POP DX POP DI POP CX POP AX RET GET_STRING ENDP ; copied from c:\emu8086\emu8086.inc PRINT_NUM PROC NEAR PUSH DX PUSH AX CMP AX, 0 JNZ not_zero PUTC '0' JMP printed_pn not_zero: ; the check SIGN of AX, ; make absolute if it's negative: CMP AX, 0 JNS positive NEG AX PUTC '-' positive: CALL PRINT_NUM_UNS printed_pn: POP AX POP DX RET ENDP ; copied from c:\emu8086\emu8086.inc PRINT_NUM_UNS PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX ; flag to prevent printing zeros before number: MOV CX, 1 ; (result of "/ 10000" is always less or equal to 9). MOV BX, 10000 ; 2710h - divider. ; AX is zero? CMP AX, 0 JZ print_zero begin_print: ; check divider (if zero go to end_print): CMP BX,0 JZ end_print ; avoid printing zeros before number: CMP CX, 0 JE calc ; if AX