2016-12-28 8 views
2

저는 프로그래밍에 익숙하지 않아서 왜 다른 코드로 같은 결과를 얻는 지 묻고 싶었습니다. 실제로 책을 읽었고이 책의 예제는 printf (Assembler에도 있음)와 함께 있습니다. 이 경우에는 <[email protected]>이라고 표시됩니다. 이 책의 어셈블러 코드는 내 코드와 다르지만 C 코드는 동일합니다. 내 프로세서가 다른 컴퓨팅을 사용하고 있습니까?printf를 사용하든 puts를 사용하든 관계없이 디스 어셈블 할 때 puts가 표시되는 이유는 무엇입니까?

#include <stdio.h> 

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

코드 2 : 분해

#include <stdio.h> 

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

코드 1 :

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 <[email protected]> 
    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. 

코드 1 (문제점 호 <+34><[email protected]>에서이다)210 분해 코드 2 :

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 <[email protected]> 
    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. 
+4

GNU'gcc'는'printf ("some string \ n")'을'puts ("some string");로 대체하는 것이 좋습니다. 최적화입니다. 'puts()'는 형식 문자열을 해석 할 필요가 없습니다. –

+1

관련 : [printf가 C 프로그램에 자동으로 puts로 대체 될 수 있습니까?] (https://stackoverflow.com/questions/25816659/can-printfget-replaced-by-puts-automatically-in-ac-program) –

+0

도움 주셔서 감사합니다! :) –

답변

2

puts 함수는 모두 기능 (NO 형식 문자열 디코딩) 및 인수 전달에 더 간단하므로 바람직하다.

예를 들어, System V ABI x86 호출 규칙은 RAX에 XMM (YMM) 인수 (printf은 가변)의 수를 설정해야합니다. 은 RDI으로 전달되는 인수가 하나뿐이므로 더 쉽습니다.

+0

위의 의견과 함께 나를 도왔습니다 –