#include <stdio.h>
extern char *printbin(unsigned char);
int main(void)
{
unsigned int x;
printf("enter the character's ascii value in hex: \n");
scanf("%x",&x);
printf("The binary format for character %c is %s\n", x, printbin((unsigned char)x));
return 0;
}
The above C function is calling the below assembly function to print the binary of the unsigned char input. Donibble is basically just supposed to bitshift 4 times and each time it will write the carry flag to str using 0x30/0x31 for 0 and 1. I'm trying to iterate through the string and replace each character in %esi, but for some reason there is a segmentation fault at isone. Am I going about this the wrong way? I'm not sure if I'm using the dereferencing correctly with esi. Another issue is the str variable is stored at 0x100d00 according to the symbol table, but when I check x/x 0x100d00 in gdb it shows bytes that are completely unrelated to the string I stored there. Overall I'm just lost, any help is appreciated.
.globl printbin # receives a char from a C program, returns binary of it by bit shifting and writing each carry flag to a string
.data
str:
.string "ninebytes" # 9 byte long string, 8 for 0,1 1 for space
.text
# frrst argument is char, returns char pointer(array)
printbin:
prologue:
push %ebp
movl %esp, %ebp
push %esi
push %ebx
input:
movl 8(%ebp), %edx # move unsigned char argument to dl(converted hex to decimal)
movl str, %esi # keep pointer to str in %esi
movl str, %eax # keep first pointer of string in %eax to return
call donibble # call donibble twice
movl $0x20, (%esi)
inc %esi
call donibble
end:
pop %ebx
pop %esi
movl %ebp, %esp
pop %ebp
ret
donibble:
# stores bits in %dl register to a string where the starting pointer is in %esi
push %ecx # save previous ecx
movl 0, %ecx # count to 3
counter:
cmp %ecx, 4
jl bitshift # if ecx is less than 4 (bitshift 4 times)
pop %ecx # else end
ret
bitshift:
inc %ecx # add one to ecx
shl $1, %dl # left shift dl
je isone # if carry flag is 1 write 1 to string
jmp iszero # if CF is 0 write 0 to string
isone:
movl $0x31, (%esi) # move 1 to string
incl %esi # next char
jmp counter
iszero:
movl $0x30, (%esi) # move 0 to string
incl %esi # next char
jmp counter