We need a buffer large enough to hold the Binary ASCII String + a Carrage Return (ASCII 10), since we will be converting an 8-bit number, a 9 byte buffer will be large enough.
Next, we need to set our loop counter to TOTAL_BITS_OF_NUMBER - 1, in this case 7 (8-bit number - 1).
Next, we need a way to test each bit (There are many ways to do this), we will use SHL (Shift Left) to move each bit into the Carry Register and decide what to do from there. We can jump to a label and move a "0" or "1" into our buffer depening on what is in the Carry Flag, or we can use SETcc (Set bit on Condition), we will use SETC (Set bit if Carry). This instruction will set a bit to 1 if carry flag has a one, 0 otherwise. We then add ASCII 0 ("0") to this bit, increment our pointer, and decrement our loop counter and loop back for the next bit if counter is not -1.
SHL is destructive, meaning for every MSB you shift into the Carry Flag, the LSB gets replaced with a 0.
global main sys_write equ 1 sys_exit equ 60 stdout equ 0 section .data fmtint db "%ld", 10, 0 section .bss Num resb 9 section .text main: mov rsi, 89 mov rdi, Num call IntToBin8 mov rdx, rax mov rsi, Num mov rdi, stdout mov rax, sys_write syscall mov rdi, 0 mov rax, sys_exit syscall IntToBin8: mov rcx, 7 mov rdx, rdi .NextNibble: shl sil, 1 setc byte [rdi] add byte [rdi], "0" add rdi, 1 sub rcx, 1 jns .NextNibble mov byte [rdi], 10 mov rax, rdi sub rax, rdx inc rax ret
IntToBin8: mov rcx, 7 mov rdx, rdi
Here we set out loop counter RCX to 7 (TOTAL_BITS_OF_NUMBER - 1)
Next, we save the address of our buffer into RDX to hold the Binary ASCII.
.NextNibble: shl sil, 1 setc byte [rdi] add byte [rdi], "0" add rdi, 1 sub rcx, 1 jns .NextNibble
1. Shift a bit into the Carry Flag
2. If carry flag = 1 set byte to 1 at pointer in RDI, otherwhise set to 0
3. Add ASCII "0" (48) to this byte to convet to an ASCII number
4. Add 1 to our buffer pointer to increment it
5. Subtract 1 from our loop counter
6. If sign flag is not set (RCX != -1) loop back to .NextNibble for the next bit
mov byte [rdi], 10 mov rax, rdi sub rax, rdx inc rax ret
1. Now that our loop is done, move a LineFeed into out buffer.
2. Move the current pointer address into RAX
3. Subract the original pointer address (RDX) from the current pointer address, then increment it by one to return the number of bytes in out buffer.
This is what the SHL looks like:
For you to do:
How would you add spaces to the output so 01011001 would become 0101 1001?