2

Why it doesn't print the character if I use register instead of at memory?

here's code:

mov eax,97
mov ebp,eax
call print_char

print_char:
pusha          
mov eax,4       
mov ebx,1       
mov ecx,ebp 
mov edx,1       
int 80h         
popa            
ret
Mysticial
  • 464,885
  • 45
  • 335
  • 332
The Mask
  • 17,007
  • 37
  • 111
  • 185

1 Answers1

3

It's not that you can't use a register... it's that you're not providing the address a string (specifically a C-string, a null-terminated1 array of characters).

Quick background info for those unfamiliar with int 80h system calls on linux, here is the calling convention on x86:

System call #  - eax
Parameters     - ebx, ecx, edx, esi, edi, ebp

So, you're calling system call 4, which is sys_write. The C signature is:

ssize_t sys_write(unsigned int fd, const char * buf, size_t count)

You can see that the second parameter (ecx) is supposed to be a const char* buf, which is a pointer to a string. You're passing 97, which is certainly not a valid address, and you're probably seg-faulting.

A quick-and-dirty method for your example, which uses the stack to store that one-character string:

print_char:    # Takes char in ebp
    pusha
    mov    eax, 4     # sys_write
    mov    ebx, 1     # stdout

    push   ebp
    mov    ecx, esp   # buf  (char on stack)

    mov    edx, 1     # just one character
    int    80h        # linux syscall
    pop    ebp
    popa
    ret

This should print the letter 'a' (ASCII 97) to stdout. If you wanted to print a decimal 97, then just like in C, where you'd be calling something from the printf family, you need to convert that decimal number to a string before trying to write it to stdout.


1 - Technically the string doesn't need to be null-terminated here since you can specify printing just one character.

Community
  • 1
  • 1
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328