Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between puts and printf in C compiled into Assembly language

Tags:

c

gcc

assembly

This is my C program using puts():

#include <stdio.h>
int main(void){
puts("testing");
}

After using gcc -S -o sample.s sample.cto 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.

like image 912
tintheanh Avatar asked Apr 30 '16 22:04

tintheanh


People also ask

What is the difference between printf () and puts ()?

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.

What is puts in assembly language?

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.

Why do we use puts instead of printf?

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.

What does printf do in assembly?

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.


1 Answers

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);
}
like image 191
perror Avatar answered Sep 28 '22 06:09

perror