Why it shows puts when I disassemble no matter whether I'm using printf or puts? [duplicate]
Asked Answered
I

1

2

I'm pretty new to programming and wanted to ask why I get the same result with different code. I'm actually reading a book and the example in the book is with printf (also in Assembler). In this case it says <printf@plt>. The assembler code in the book differs from mine but C Code is the same. Is my processor just computing different?

(Problem is at call <+34> <puts@plt>)

Code 1:

#include <stdio.h>

int main()
{
    int i;
    for(i=0; i<10; i++)
    {
        printf("Hello, world!\n");
    }
    return 0;
}

Code 2:

#include <stdio.h>

int main()
{
    int i;
    for(i=0; i<10; i++)
    {
        puts("Hello, world!\n");
    }
    return 0;
}

Code 1 disassembled:

Dump of assembler code for function main:
   0x080483eb <+0>: lea    ecx,[esp+0x4]
   0x080483ef <+4>: and    esp,0xfffffff0
   0x080483f2 <+7>: push   DWORD PTR [ecx-0x4]
   0x080483f5 <+10>:    push   ebp
   0x080483f6 <+11>:    mov    ebp,esp
   0x080483f8 <+13>:    push   ecx
=> 0x080483f9 <+14>:    sub    esp,0x14
   0x080483fc <+17>:    mov    DWORD PTR [ebp-0xc],0x0
   0x08048403 <+24>:    jmp    0x8048419 <main+46>
   0x08048405 <+26>:    sub    esp,0xc
   0x08048408 <+29>:    push   0x80484b0
   0x0804840d <+34>:    call   0x80482c0 <puts@plt>
   0x08048412 <+39>:    add    esp,0x10
   0x08048415 <+42>:    add    DWORD PTR [ebp-0xc],0x1
   0x08048419 <+46>:    cmp    DWORD PTR [ebp-0xc],0x9
   0x0804841d <+50>:    jle    0x8048405 <main+26>
   0x0804841f <+52>:    mov    eax,0x0
   0x08048424 <+57>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x08048427 <+60>:    leave  
   0x08048428 <+61>:    lea    esp,[ecx-0x4]
   0x0804842b <+64>:    ret    
End of assembler dump.

Code 2 disassembled:

Dump of assembler code for function main:
   0x080483eb <+0>: lea    ecx,[esp+0x4]
   0x080483ef <+4>: and    esp,0xfffffff0
   0x080483f2 <+7>: push   DWORD PTR [ecx-0x4]
   0x080483f5 <+10>:    push   ebp
   0x080483f6 <+11>:    mov    ebp,esp
   0x080483f8 <+13>:    push   ecx
   0x080483f9 <+14>:    sub    esp,0x14
   0x080483fc <+17>:    mov    DWORD PTR [ebp-0xc],0x0
   0x08048403 <+24>:    jmp    0x8048419 <main+46>
=> 0x08048405 <+26>:    sub    esp,0xc
   0x08048408 <+29>:    push   0x80484b0
   0x0804840d <+34>:    call   0x80482c0 <puts@plt>
   0x08048412 <+39>:    add    esp,0x10
   0x08048415 <+42>:    add    DWORD PTR [ebp-0xc],0x1
   0x08048419 <+46>:    cmp    DWORD PTR [ebp-0xc],0x9
   0x0804841d <+50>:    jle    0x8048405 <main+26>
   0x0804841f <+52>:    mov    eax,0x0
   0x08048424 <+57>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x08048427 <+60>:    leave  
   0x08048428 <+61>:    lea    esp,[ecx-0x4]
   0x0804842b <+64>:    ret    
End of assembler dump.
Indignity answered 28/12, 2016 at 23:12 Comment(6)
GNU gcc thinks it is a good idea to replace printf("some string\n") with puts("some string"); — so it does. It's an optimization; puts() doesn't have to interpret the format string.Mentally
Related: Can printf get replaced by puts automatically in a C program?Georgeanngeorgeanna
Ok thanks for help! :)Indignity
Be aware that compilers can modify and replace any of the standard C library. It's common to rewrite the memory and string functions like memset, memcpy and strlen for example.Rundgren
Another question/answer that may be of value: #37436484Sojourn
That's interesting, I wouldn't have guessed that gcc would do this optimization at -O0. (But note that gcc -O0 doesn't mean literal braindead translation of source to asm: #33279257)Cardiogram
A
2

The puts function is preferred because it is simpler to in both functionality (no format string decoding) and argument passing.

For instance, System V ABI x86 calling conventions require to set number of XMM (YMM) arguments (printf is variadic) in RAX. puts is easier, as there is only single argument passed with RDI.

Abisia answered 28/12, 2016 at 23:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.