컴파일러에서 함수 이름 앞에 밑줄이 붙는 이유는 무엇입니까?
C 앱의 어셈블리 코드를 보면 다음과 같습니다.
emacs hello.c
clang -S -O hello.c -o hello.s
cat hello.s
함이앞는밑예줄에름수)이.callq _printf
은 왜 ?) 이것은 왜 행해지고 어떤 이점을 가지고 있습니까?
예:
안녕하세요.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *myString = malloc(strlen("Hello, World!") + 1);
memcpy(myString, "Hello, World!", strlen("Hello, World!") + 1);
printf("%s", myString);
return 0;
}
안녕하세요.
_main: ; Here
Leh_func_begin0:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $14, %edi
callq _malloc ; Here
movabsq $6278066737626506568, %rcx
movq %rcx, (%rax)
movw $33, 12(%rax)
movl $1684828783, 8(%rax)
leaq L_.str1(%rip), %rdi
movq %rax, %rsi
xorb %al, %al
callq _printf ; Here
xorl %eax, %eax
popq %rbp
ret
Leh_func_end0:
1974년쯤 UNIX가 C에서 다시 작성되었을 때, UNIX의 작성자들은 이미 광범위한 어셈블리어 라이브러리를 가지고 있었고, 새로운 C와 C 호환 코드의 이름을 뒤로 돌아가서 모든 기존 코드를 수정하는 것보다 더 쉬웠습니다.20년이 지난 지금, 어셈블러 코드는 모두 5번 다시 작성되었고, UNIX C 컴파일러, 특히 COFF와 ELF 객체 파일을 만드는 컴파일러는 더 이상 밑줄을 추가하지 않습니다.
C 컴파일의 어셈블리 결과에 밑줄을 추가하는 것은 해결책으로 발생한 이름맹그 규칙일 뿐입니다.그것은 (제가 아는 한) 특별한 이유 없이 주변에 머물렀고, 지금은 클랑으로 진출했습니다.
어셈블리 외부에서 C 표준 라이브러리는 종종 마법의 개념을 전달하고 이를 우연히 발견한 일반 프로그래머에게 건드리지 않기 위해 밑줄이 붙은 구현 정의 함수를 가지고 있습니다.
많은 컴파일러들이 C를 어셈블리 언어로 변환하고, 그 위에서 어셈블리어를 실행하여 객체 파일을 생성하는 데 사용되었습니다.바이너리 코드를 직접 생성하는 것보다 훨씬 쉽습니다.(AFAIK GCC는 여전히 이를 수행합니다.하지만 자체 조립기도 있습니다.)이 변환 중에 함수 이름은 어셈블리 소스의 레이블이 됩니다.를 들어) (으)라는 기능이 있다면, (으)ㄹ 수 .ret
하만지, 일부조은혼동수그라있것벨수생다있니습각할아고 (은 라벨이 수 콜론을 로 하지 않기예를 들어 YASM은 레이블이 거의 모든 위치에 나타날 수 있고 콜론이 필요하지 않기 때문에 대부분 그렇습니다. 앞에 .$
만약 당신이 라벨을 원한다면.ret
.)
C 생성 레이블에 문자(예: 밑줄)를 추가하는 것은 자신의 C 친화적인 어셈블리어를 작성하거나 레이블이 어셈블리 지침/지시와 충돌할 것을 걱정하는 것보다 훨씬 쉬웠습니다.
요즘은 어셈블러와 컴파일러가 조금 발전했고, 어쨌든 대부분의 사람들은 C 레벨 이상에서 일합니다.따라서 C에서 이름을 망치는 원래의 필요성은 거의 사라졌습니다.
언뜻 보기에 운영 체제는 PC에서 실행되는 Unix/Unix와 유사합니다.제 말에 따르면 생성된 어셈블리 언어에서 _printf를 찾는 것은 그리 놀라운 일이 아닙니다.Cprintf는 I/O를 수행하는 기능입니다.따라서 요청된 I/O를 수행하는 것은 커널 + 드라이버의 책임입니다.
모든 유닉스/유닉스 계열 OS에서 사용되는 기계 명령 경로는 다음과 같습니다.
printf (C code) -> _printf (libc) -> trap -> 커널 + 드라이버 작업 -> 트랩에서 반환 -> _printf (libc) -> printf 완료에서 반환 -> C 코드의 다음 기계 명령어
이 어셈블리 코드 추출물의 경우 컴파일러에 의해 C printf가 인라인화되어 어셈블리 코드에 _printf 진입점이 표시되는 것처럼 보입니다.
C printf가 접두사(이 경우 밑줄)로 장식되지 않도록 하려면 모든 C 헤더에서 다음과 같은 명령을 사용하여 _printf를 검색하는 것이 가장 좋습니다.
/usr/adm -name *.h -execgrep _printf {} \; -print를 찾습니다.
언급URL : https://stackoverflow.com/questions/5908568/what-is-the-reason-function-names-are-prefixed-with-an-underscore-by-the-compile
'programing' 카테고리의 다른 글
기존 프로젝트에 ASP.NET MVC5 ID 인증 추가 (0) | 2023.06.21 |
---|---|
요구 사항을 사용자 지정하는 방법.여러 환경을 위한 txt? (0) | 2023.06.21 |
UTL_FILE.FOPEN() 프로시저가 디렉터리 경로를 수락하지 않습니까? (0) | 2023.06.21 |
Angular 2의 AoT 컴파일러용 롤업 사용 및 Moment.js 가져오기 (0) | 2023.06.21 |
Oracle 오류 PLS-00323: 하위 프로그램 또는 커서가 패키지 사양으로 선언되었으며 패키지 본문에 정의되어야 합니다. (0) | 2023.06.21 |