PStag
PStag

Reputation: 293

Assembler. Printing value to screen as binary

Is there a instruction to print a value from assembler as binary? SO far I have only found instructions for using ASCII characters.

I'm using NASM.

I have been using.

mov ecx, var0
mov edx, 1
mov ebx, 1
mov eax, 4
int 0x80

To print

Upvotes: 0

Views: 7244

Answers (1)

Goodies
Goodies

Reputation: 4681

No, there isn't. However, you can write a fairly simple function for this. Because I'm not on my Linux machine, I cannot do this right now, but this is how I would do it:

First, psuedocode. First, let's assume we are printing a 4-bit number. Say b1010 = (10 decimal). We first want:

  1. b1010 & b1000 = b1000
  2. b1010 & b0100 = b0
  3. b1010 & b0010 = b10
  4. b1010 & b0001 = b0

So it would seem to me, with a four bit number, we would need to & each bit with 1 << (4-i) where i is the index. If it is non-zero, return a 1. Otherwise, return a 0.

Now, we only have a 1 or 0, but we need to actually add to it to get the string value. The easiest way to do that is to add the ascii value '0' which is 48d or 0x30. In python, this would print it out in binary: print("\x31\x30\x31\x30").

So now, we do it in C:

void printBinary(uint32_t n) {
    for (size_t i = 1; i <= 32; ++i)
        if (n & (1 << (32 - i)))
            printf("%c", 0x30 + 1);
        else
            printf("%c", 0x30 + 0);
}

Without testing, this is the best that I can come up with:

printBinary:
    push ebp
    mov ebp, esp

    mov esi, [ebp+8] ;// __cdecl calling convention. get parameter from the stack
    mov ecx, 1 ;// This will be used for our counter
    .loop:
    mov eax, 1 ;// 1 will be shifted
    mov ebx, 32 ;// 32 is the size of the number we are printing
    sub ebx, ecx ;//  offset from the counter.
    shl eax, ebx ;// shift left. This is the 1 << (32 - i) part in C.
    and eax, esi ;// and it
    test eax, eax ;// if it is zero...
    jz .print ;// then print '0'
    mov eax, 1 ;// otherwise, print '1'
    .print
    push ecx ;// save ecx counter for later
    mov ecx, eax
    add ecx, 0x30
    mov eax, 4 ;// syscall for output
    mov ebx, 1 ;// stdout
    mov edx, 1 ;// only printing one byte
    int 0x80 ;// call the kernel
    pop ecx ;// replace the counter
    inc ecx
    cmp ecx, 32
    jle .loop
    mov esp, ebp
    pop ebp
    ret

This is very likely incorrect to some degree as I cannot test it yet, but hopefully this gives you a structure to follow. Hopefully, you can call it with:

push 10
call printBinary

That's the goal, anyways.

Upvotes: 1

Related Questions