I'm using the MASM syntax with Irvine32 Library on Visual Studio.
I've attempted to make this program convert binary to decimal and vise versa, and now I'm stuck on how to convert binary to hexa and vise versa
Here's my code
INCLUDE Irvine32.inc
.data
str1 BYTE ">>> Please select the conversion type: ", 0
str2 BYTE " 1. Binary to Decimal", 0
str3 BYTE " 2. Decimal to Binary", 0
str4 BYTE " 3. Exit", 0
str5 BYTE "-----------------------------------------", 0
str6 BYTE "Enter your choice: ", 0
str7 BYTE "Please Enter 8-bit binary digits (e.g., 11110000): ", 0
str8 BYTE "The decimel integer of ", 0
str9 BYTE " is ", 0
str10 BYTE " ", 0
str11 BYTE "Please Enter a decimal integer less than 256: ", 0
str12 BYTE "The binary of ", 0
str13 BYTE " is ", 0
str14 BYTE " ", 0
str15 BYTE "Bye.", 0
choice DWORD ?
num1 BYTE 9 DUP(? )
num2 WORD ?
numLength DWORD 0
outLoop DWORD 0
base DWORD 2
deciNum DWORD ?
.code
main PROC
_mainprog : ;USED TO DISPLAY THE MENU & EXIT
mov edx, offset str1
call WriteString
call crlf
mov edx, offset str2
call WriteString
call crlf
mov edx, offset str3
call WriteString
call crlf
mov edx, offset str4
call WriteString
call crlf
mov edx, offset str5
call WriteString
call crlf
mov edx, offset str6
call WriteString
call ReadDec ;DISPLAY OUTPUT
mov choice, eax ;EAX = 1
cmp choice, 1 ;IF = 1
je _proc1 ;JUMP TO PROC1
cmp choice, 2 ;IF = 2
je _proc2 ;JUMP TO PROC2
cmp choice, 3 ;IF = 3
je _proc3 ;JUMP TO PROC3
_proc1 : ;BINARY TO DECIMAL
mov edx, offset str7
call WriteString
mov edx, offset num1 ;ASSIGN NUM1 TO EDX TO WRITE THE BINARY IN STRING FORMAT
mov ecx, sizeof num1 ;ASSIGN TO ECX TO ACT AS THE COUNTER (COUNT THE LENGTH OF THE BINARY DIGIT)
call ReadString ;USER INPUT BINARY NUMBER
mov numLength, eax ;USER INPUT EAX STORED IN NUMLENGTH
mov eax, 0 ;EAX ASSIGNED TO 8
mov esi, 0 ;ESI TO ACCESS THE STRING BINARY INPUT THAT WE ENTERED
mov ecx, numLength
whileProc1 :
cmp ecx, 0 ;COMPARE COUNTER WITH 0
je printResult ;IF ECX =/ 0, IT WILL NOT JUMP TO PRINT RESULT
mov outLoop, ecx ;8 ASSIGNED TO OUTLOOP AND ASSIGNED TO REGISTER ECX
ifProc :
cmp num1[esi], '0' ;IF 1ST VALUE IN THE BINARY DIGIT = 0
je incEsiProc ;JUMP TO INCREASE ESI PROC
elseIfProc:
cmp num1[esi], '1' ;IF 1ST VALUE IN BINARY DIGIT = 1
mov ecx, numLength ;NUMLENGTH ASSIGNED TO ECX
sub ecx, esi ;
dec ecx
mov eax, 1
whileProc2 :
je stopProc
mov ebx, base
mul ebx
dec ecx
jmp whileProc2
stopProc :
add deciNum, eax
jmp incEsiProc
incEsiProc :
inc esi
mov ecx, outLoop
dec ecx
jmp whileProc1
printResult :
mov edx, offset str8
call WriteString
mov edx, offset num1
call WriteString
mov edx, offset str9
call WriteString
mov eax, deciNum
call WriteDec
mov edx, offset str10
call WriteString
call crlf
call crlf
jmp _mainprog
_proc2: ;DECIMAL TO BINARY
mov edx, offset str11
call WriteString
mov edx, offset num2
call ReadInt
mov num2, ax
mov ebx, 1
mov edx, offset str12
call WriteString
mov ax, num2
call WriteDec
mov edx, offset str13
call WriteString
call WriteBinB
mov edx, offset str14
call WriteString
call crlf
call crlf
jmp _mainprog
_proc3:
mov edx, offset str15
call WriteString
call crlf
call WaitMsg
exit
main ENDP
END main
Able to ask user for input a number and convert hexa to binary/decimal and vise versa
This is how program looks now, I used this algorithm for conversion binary string to integer. :)
include \masm32\include\Irvine32.inc
includelib \masm32\lib\Irvine32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data
menu BYTE "-----------------------------------------",13,10
BYTE " Please select the conversion type ",13,10
BYTE "-----------------------------------------",13,10
BYTE " 1. Binary to Decimal",13,10
BYTE " 2. Decimal to Binary",13,10
BYTE " 3. Binary to Hex",13,10
BYTE " 4. Hex to Binary",13,10
BYTE "-----------------------------------------",13,10
BYTE " 5. Exit",13,10
BYTE "-----------------------------------------",13,10
BYTE "Enter your choice: ",0
menu_error BYTE "*** You entered wrong number. Try again.", 0
bin_input_msg BYTE "Please enter 8-bit binary digits (e.g., 11110000): ", 0
bin_string_error BYTE "*** Cannot convert binary string to integer. Try again.", 0
bin_msg_1 BYTE "The binary of ", 0
dec_input_msg BYTE "Please enter a decimal integer less than 256: ", 0
dec_input_error BYTE "*** Enter value from range 0 - 255.", 0
dec_msg_1 BYTE "The decimal integer of ", 0
hex_input_msg BYTE "Please enter a hex value: ", 0
hex_msg_1 BYTE "The hex of ", 0
is BYTE " is ", 0
exit_msg BYTE "Bye.", 0
binary_string BYTE 9 DUP(0)
InitFlag DB 0
consoleInHandle DWORD ? ; handle to console input device
consoleOutHandle DWORD ?
;----------------------------------------------------------------------
CheckInit MACRO
; Helper macro
; Check to see if the console handles have been initialized
; If not, initialize them now.
LOCAL exit
cmp InitFlag,0
jne exit
call Initialize
exit:
ENDM
;----------------------------------------------------------------------
.code
main PROC
;----------------------------------------------------------------------
; MENU
_mainprog:
call Clrscr
mov edx, offset menu
call WriteString
call ReadDec ;eax = user's choice
call crlf
cmp eax, 1
je _bin_dec
cmp eax, 2
je _dec_bin
cmp eax, 3
je _bin_hex
cmp eax, 4
je _hex_bin
cmp eax, 5
je _exit
jmp _wrong_number
;----------------------------------------------------------------------
; BINARY TO DECIMAL
_bin_dec:
call BinaryString2Int
mov edx, offset dec_msg_1
call WriteString
mov edx, offset binary_string
call WriteString
mov edx, offset is
call WriteString
call WriteDec
call _new_line
jmp _mainprog
;----------------------------------------------------------------------
; DECIMAL TO BINARY
_dec_bin:
mov edx, offset dec_input_msg
call WriteString
call ReadDec
cmp eax,255 ;check if value is 0 - 255
ja GreaterThan255
mov edx, offset bin_msg_1
call WriteString
call WriteDec
mov edx, offset is
call WriteString
mov ebx, 1 ; 1 - byte, 2 - word, 4 - dbl word
call WriteBinB
call _new_line
jmp _mainprog
GreaterThan255:
call crlf
mov edx, offset dec_input_error
call WriteString
call _new_line
jmp _dec_bin
;----------------------------------------------------------------------
; BINARY TO HEX
_bin_hex:
call BinaryString2Int
mov edx, offset hex_msg_1
call WriteString
mov edx, offset binary_string
call WriteString
mov edx, offset is
call WriteString
call WriteHex
call _new_line
jmp _mainprog
;----------------------------------------------------------------------
; HEX TO BINARY
_hex_bin:
mov edx, offset hex_input_msg
call WriteString
call ReadHex
mov edx, offset bin_msg_1
call WriteString
call WriteHex
mov edx, offset is
call WriteString
mov ebx,4 ; 1 - byte, 2 - word, 4 - dbl word
call WriteBinB
call _new_line
jmp _mainprog
;----------------------------------------------------------------------
; NUMBER IS NOT ON THE MENU LIST
_wrong_number:
mov edx, offset menu_error
call WriteString
call _new_line
jmp _mainprog
;----------------------------------------------------------------------
; NEW LINE
_new_line:
call crlf
call crlf
call WaitMsg
call crlf
ret
;----------------------------------------------------------------------
; EXIT
_exit:
mov edx, offset exit_msg
call WriteString
call crlf
call WaitMsg
exit
main ENDP
BinaryString2Int Proc
;----------------------------------------------------------------------
; INPUT - BINARY STRING
_bin_string_input:
mov edx, offset bin_input_msg
call WriteString
mov edx, offset binary_string
mov ecx, sizeof binary_string
call ReadString
;----------------------------------------------------------------------
; BINARY STRING TO INT
; Algorithm taken from -> https://stackoverflow.com/a/49548057/20889367
mov edi, offset binary_string
movzx eax, byte ptr [edi] ; start with the first digit
sub eax, '0' ; convert from ASCII to number
cmp al, 1 ; check that it's a decimal digit [0..1]
jbe _loop_entry ; too low -> wraps to high value, fails unsigned compare check
xor eax,eax ; else: bad first digit: return 0
jmp conversionError ;ret
; rotate the loop so we can put the JCC at the bottom where it belongs
; but still check the digit before messing up our total
_next_digit:
; lea eax, [eax*4 + eax]
lea eax, [eax*2 + ecx] ; total = total*2 + digit
; imul eax, 2 / add eax, ecx
_loop_entry:
inc edi
movzx ecx, byte ptr[edi]
sub ecx, '0'
cmp ecx, 1
jbe _next_digit
ret ; return with total in eax
conversionError:
call crlf
mov edx, offset bin_string_error
call WriteString
call crlf
call crlf
jmp _bin_string_input
ret
BinaryString2Int Endp
Initialize PROC private
;----------------------------------------------------------------------
; Get the standard console handles for input and output,
; and set a flag indicating that it has been done.
; Updated 03/17/2003
pushad
INVOKE GetStdHandle, STD_INPUT_HANDLE
mov [consoleInHandle],eax
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov [consoleOutHandle],eax
mov InitFlag,1
popad
ret
Initialize ENDP
END main