This is my C program using puts()
:
#include <stdio.h>
int main(void){
puts("testing");
}
After using gcc -S -o sample.s sample.c
to compiled it into Assembly, this is what I got:
.file "sample.c"
.section .rodata
.LC0:
.string "testing"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call puts
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.5 20110214 (Red Hat 4.4.5-6)"
.section .note.GNU-stack,"",@progbits
I did the same way, this time I was using printf()
instead of puts and this is what I got:
.file "sample.c"
.section .rodata
.LC0:
.string "testing"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, %eax //this is the difference
movl %eax, (%esp)
call printf
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.5 20110214 (Red Hat 4.4.5-6)"
.section .note.GNU-stack,"",@progbits
Here is what I don't understand, the printf()
function mov $.LC0
to %eax
, then mov %eax
to (%esp)
while the puts()
function mov %.LC0
directly to (%esp)
.
I don't know why is that.
the printf() function is used to print both strings and variables to the screen while the puts() function only permits you to print a string only to your screen.
C library function - puts() The C library function int puts(const char *str) writes a string to stdout up to but not including the null character. A newline character is appended to the output.
puts() can be preferred for printing a string because it is generally less expensive (implementation of puts() is generally simpler than printf()), and if the string has formatting characters like '%s', then printf() would give unexpected results.
When printf is called, it executes and prints the vector, byte per byte, from the first (the one you passed), until a signal character that tells it to stop. That signal character is the 0 after the Enter on the string.
The big difference between the two functions, at the assembly level, is that the puts()
function will just take one argument (a pointer to the string to display) and the printf()
function will take one argument (a pointer to the format string) and, then, an arbitrary number of arguments in the stack (printf()
is a variadic function).
Note that, there is absolutely no check of the number of arguments, it is only depending of the number of time the character %
is encountered in the format string. For example, this specificity is used in format string format bug exploitation method to interactively explore the content of the stack of a process.
So, basically, the difference is that puts()
has only one argument and printf()
is a variadic function.
If you want to better understand this difference, try to compile:
#include <stdio.h>
int main(void) {
printf("testing %d", 10);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With