programing

"std"에 "std"가 포함되지 않고 C에서 무엇을 할 수 있습니까?'C'의 일부일까요, 아니면 그냥 라이브러리일까요?

prostudy 2022. 7. 1. 21:12
반응형

"std"에 "std"가 포함되지 않고 C에서 무엇을 할 수 있습니까?'C'의 일부일까요, 아니면 그냥 라이브러리일까요?

주관적인 질문이나 반복적인 질문이라면 죄송합니다.검색하기가 좀 어려워서 어떤 용어를 넣어야 할지 잘 모르겠더라고요.

것은 기본 도구/ 알고 싶은 것은 에 표준 가 포함되어 때 입니다.stdio ★★★★★★★★★★★★★★★★★」stdlib.

에 없다, 없다, 없다, 어떻게 돼요?printf(),fopen()

또한 이러한 라이브러리는 기술적으로 "C" 언어의 일부입니까, 아니면 매우 유용하고 효과적으로 필수적인 라이브러리입니까?

printf(), fopen() 등이 없는 경우 어떻게 해야 합니까?

사용하고 있는 시스템의 인터페이스 방법을 알고 있는 한, 표준 C 라이브러리 없이도 사용할 수 있습니다.메모리가 몇 킬로바이트밖에 없는 임베디드 시스템에서는 표준 라이브러리를 전혀 사용하지 않을 수 있습니다.

다음은 Linux 및 Windows에서 표준 C 함수를 사용하지 않는 경우의 Hello World! 예입니다.

예를 들어 Linux에서는 Linux 시스템콜을 인라인어셈블리로 직접 호출할 수 있습니다.

/* 64 bit linux. */

#define SYSCALL_EXIT 60
#define SYSCALL_WRITE 1

void sys_exit(int error_code)
{
    asm volatile
    (
        "syscall"
        : 
        : "a"(SYSCALL_EXIT), "D"(error_code)
        : "rcx", "r11", "memory"
    );
}

int sys_write(unsigned fd, const char *buf, unsigned count)
{
    unsigned ret;

    asm volatile
    (
        "syscall"
        : "=a"(ret)
        : "a"(SYSCALL_WRITE), "D"(fd), "S"(buf), "d"(count)
        : "rcx", "r11", "memory"
    );
    
    return ret;
}

void _start(void)
{
    const char hwText[] = "Hello world!\n";

    sys_write(1, hwText, sizeof(hwText));
    sys_exit(12);
}

시스템 콜을 발신하는 방법에 대해서는, 「syscall」의 메뉴얼 페이지를 참조할 수 있습니다.인텔 x86_64에서는 시스템콜 ID를 RAX에 입력하면 반환값이 RAX에 저장됩니다.인수는 RDI, RSI, RDX, R10, R9 및 R8 순으로 입력해야 합니다(인수가 사용되는 경우).

이것을 입수하면 인라인어셈블리를 gcc로 쓰는 방법을 찾아봐야 합니다.syscall 명령어는 RCX, R11 레지스터 및 메모리를 변경하기 때문에 이를 clobber 목록에 추가하여 GCC가 이를 인식하도록 합니다.

GNU 링커의 기본 엔트리 포인트는 _start 입니다.보통 표준 라이브러리에서 제공하지만, 표준 라이브러리가 없으면 제공해야 합니다.원래대로 되돌릴 발신자 함수가 없기 때문에 실제로는 함수가 아닙니다.따라서 프로세스를 종료하기 위해 다른 시스템 호출을 해야 합니다.

컴파일 대상:

gcc -nostdlib nostd.c 

그리고 그것은 출력한다.Hello world! 나가세요.

Windows 에서는, 시스템 콜은 공개되지 않고, 다른 추상화 레이어, kernel32.dll 뒤에 숨겨집니다.이것은 프로그램이 시작되었을 때 항상 로드됩니다(원하든 원하지 않든 말이죠.따라서 Windows SDK에서 windows.h를 포함하여 Win32 API를 정상적으로 사용할 수 있습니다.

#include <windows.h>

void _start(void)
{
    const char str[] = "Hello world!\n";
    HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD written;

    WriteFile(stdout, str, sizeof(str), &written, NULL);
    ExitProcess(12);
}

windows.h표준 C 라이브러리와는 관계가 없습니다.윈도우를 사용하다

다음과 같이 MinGW 도구를 사용하여 컴파일할 수 있습니다.

gcc -nostdlib C:\Windows\System32\kernel32.dll nostdlib.c

그러면 컴파일러는 Import 의존관계를 해결하고 프로그램을 컴파일할 수 있습니다.

프로그램을 분해하면 코드만 표시되며 표준 라이브러리 블러트는 표시되지 않습니다.

따라서 표준 라이브러리 없이 C를 사용할 수 있습니다.

C 표준에는 다음과 같이 명시되어 있다(5.1.2.3/5):

적합 실장에 관한 최소한의 요건은 다음과 같습니다.

: 시퀀스 포인트에서는 휘발성 오브젝트는 이전 액세스가 완료되어 후속 액세스가 아직 발생하지 않았다는 점에서 안정적입니다.

— 프로그램 종료 시 파일에 기록된 모든 데이터는 추상적 의미론에 따라 프로그램을 실행한 결과와 동일해야 합니다.

— 상호작용 장치의 입력 및 출력 역학은 7.19.3에 명시된 대로 이루어져야 한다.

따라서 표준 라이브러리 함수가 없으면 프로그램이 보장되는 유일한 동작은 휘발성 객체의 값과 관련이 있습니다.이는 보장된 파일 액세스나 "대화형 장치"를 사용할 수 없기 때문입니다."Pure C"는 표준 라이브러리 기능을 통해서만 상호작용을 제공합니다.

단, 하드웨어에는 읽기 또는 쓰기 시 특정 작업을 수행하는 특정 주소(SATA 또는 PCI 버스, 로우 비디오 메모리, 시리얼 포트, 비프음이 울리거나 LED가 깜박이는 경우)가 있을 수 있기 때문에 Pure C가 전부는 아닙니다.따라서 하드웨어에 대한 지식이 있으면 표준 라이브러리 기능을 사용하지 않고도 C로 많은 내용을 쓸 수 있습니다.C 표준 라이브러리를 구현할 수도 있지만, 이 경우 특수한 CPU 명령 및 특수 메모리 주소에 액세스해야 할 수도 있습니다.

단, 표준 삭제되어 때문에 인수를 하며 상태 하는 것 도 할 수 .main이것은 무시할 수 없습니다.리소스 제한에 따라 완전히 튜링됩니다만, 유일한 리소스는 자동 변수와 정적 변수이며 힙 할당은 없습니다.그다지 풍부한 프로그래밍 환경은 아닙니다.

표준 라이브러리는 C 언어 사양의 일부이지만, 모든 언어에서 "as that" 언어와 라이브러리 사이에 선이 그려지는 경향이 있습니다.개념적인 차이입니다만, 원칙적으로는 그다지 중요하지 않습니다.표준상으로는 이 두 가지가 합쳐져 있기 때문입니다.비표준적인 일을 하는 사람이라면 누구나 라이브러리만큼 쉽게 언어 기능을 제거할 수 있습니다.어느 쪽이든 결과는 C의 적합 구현이 아닙니다.

C의 "프리스턴딩" 구현은 표준의 서브셋만 구현하면 되기 때문에 위에서 설명한 바와 같이 하드웨어 고유의 확장에 의존하여 흥미로운 작업을 수행할 수 있습니다.만약 당신이 표준에 따라 "핵심 언어"와 "라이브러리"를 구별하고 싶다면, 그것은 선을 긋는 좋은 장소일 것이다.

표준 라이브러리는 C 컴파일러가 표준(예를 들어 C99)에 준거하려면 이러한 라이브러리는 "포함 가능"해야 합니다.Jessica McKellar의 과제를 여기서 살펴보세요.

http://blog.ksplice.com/2010/03/libc-free-world/

편집: 위의 링크가 끊어졌습니다(감사합니다.Oracle...).이 링크는 기사 https://sudonull.com/post/178679-Hello-from-the-libc-free-world-Part-1 를 반영하고 있다고 생각합니다.

표준 도서관이 필요하지 않다면 사용할 의무는 없습니다.많은 임베디드 시스템이 표준 라이브러리를 지원하지 않거나 어떤 이유로 사용할 수 없습니다.이 표준에서는 라이브러리가 지원되지 않는 구현에 대해서도 구체적으로 설명하고 있습니다.C99 표준 5.1.2.1 "프리스턴딩 환경:

프리랜딩 환경(운영체제의 이점 없이 C 프로그램 실행이 이루어질 수 있음)에서는 프로그램 부팅 시 호출되는 함수의 이름과 유형이 구현 정의됩니다.프리스탠딩 프로그램에 이용 가능한 라이브러리 설비는 조항 4에 의해 요구되는 최소 세트를 제외하고 구현 정의된다.

할 수 는 C99입니다.<float.h>,<iso646.h>,<limits.h>,<stdarg.h>,<stdbool.h>,<stddef.h> , , , , 입니다.<stdint.h>이러한 헤더는 타입과 매크로만을 정의하기 때문에 이들을 지원하는 함수 라이브러리가 필요하지 않습니다.

표준 라이브러리가 없으면 자신의 코드, 사용할 수 있는 비표준 라이브러리 및 인터페이스 가능한 운영 체제 호출(비표준 라이브러리 호출로 간주될 수 있음)에 전적으로 의존하게 됩니다.C 프로그램의 콜어셈블리 루틴을 사용하여 디바이스 및/또는 플랫폼상의 운영체제에 접속해야 합니다.

어떻게 할 수 있죠?전부 다!

C에는 프리프로세서를 제외하고 마법은 없습니다.

가장 어려운 것은 아마도 putchar라고 쓰는 것입니다.이것은 플랫폼에 의존하는 I/O이기 때문입니다.

그것은 당신만의 버전의 varargs를 만들고 그것을 얻으면 당신만의 vaprintf를 하고 printf와 sprintf를 하는 좋은 학부 운동이다.

1986년에 Macintosh에서 그 모든 것을 했습니다.그때 Lightspeed C에서 제공되는 stdio 루틴이 마음에 들지 않았습니다.win_putchar, win_printf, in_getchar, win_scanf를 사용하여 나만의 창 핸들러를 작성했습니다.

이 모든 과정은 부트스트래핑이라고 불리며 코딩에서 가장 만족스러운 경험 중 하나가 될 수 있습니다. 이는 상당히 실용적인 기본 설계로 작업하는 것입니다.

네, 도서관 없이도 많은 일을 할 수 있어요.

의 손길이 닿다__asm__GCC의키워드니까 할 수 있어요.

대부분의 경우 모든 프로그래밍 언어가 어셈블리에 구축되어 있으며 일부 OS에서 직접 시스템 호출을 할 수 있기 때문입니다.

대부분의 표준 라이브러리 함수는 시스템 호출에 의존하기 때문에 많은 작업을 수행할 수 없습니다.내장 C 키워드와 연산자를 사용하여 수행할 수 있는 작업에는 제한이 있습니다.시스템에 따라 다르기도 합니다.시스템에 따라서는 외부 기능을 발생시키는 방법으로 비트를 조작할 수 있는 경우가 있습니다만, 이것은 규칙이 아니라 예외일 가능성이 있습니다.

하지만 C의 우아함은 단순함에 있다.언어의 일부로 많은 기능을 포함하는 Fortran과 달리 C는 라이브러리에 상당히 의존합니다.이로 인해 플랫폼 간에 일관성이 다소 떨어지는 대신 상당한 수준의 유연성을 얻을 수 있습니다.

이것은, 예를 들면, 완전하게 다른 「라이브러리」가 실장되어 있는 operating system에서는, 커널 자체에 실장되어 있는 것과 같은 기능을 제공하기 위해서 잘 기능합니다.

라이브러리의 일부는 ANSI C의 일부로 지정되어 있습니다.그것들은 언어의 일부이지만, 그 핵심은 아닙니다.

그 중 어느 것도 언어 키워드의 일부가 아닙니다.단, 모든 C 디스트리뷰션에는 이러한 라이브러리의 실장이 포함되어 있어야 합니다.이것에 의해, 많은 프로그램의 휴대성이 보증됩니다.

먼저 C와 어셈블리를 조합하여 이론적으로 모든 기능을 구현할 수 있으므로 이론적으로는 무엇이든 할 수 있습니다.

실용적인 관점에서 보면, 라이브러리 기능은 주로 바퀴를 재창조하는 수고를 덜기 위한 것입니다.(문자열이나 라이브러리 함수 등) 구현이 더 쉬운 것도 있습니다.그 외의 것(I/O 등)은, operating system에 의해서 크게 좌우됩니다.O/S 한 번으로 자신만의 버전을 작성하는 것은 가능하지만, 프로그램의 휴대성이 떨어집니다.

그러나, PI나 삶의 의미를 계산하거나 오토마타를 시뮬레이트하는 등, 많은 유용한 일을 하는 프로그램을 작성할 수 있습니다.단, OS를 I/O에 직접 사용하지 않는 한 출력 결과를 관찰하는 것은 매우 어렵습니다.

일상 프로그래밍에서 프로그래밍 언어의 성공을 위해서는 일반적으로 유용한 고품질 표준 라이브러리와 많은 유용한 작업에 사용할 수 있는 라이브러리가 필요합니다.이것들은 퍼스트 파티 또는 서드 파티가 될 수 있지만, 반드시 존재해야 합니다.

CRT는 키워드 및 구문과 마찬가지로 C 언어의 일부입니다.C 를 사용하고 있는 경우는, 컴파일러가 타겟 플랫폼에 실장할 필요가 있습니다.

편집: C++의 STL과 동일합니다.모든 언어에는 표준 라이브러리가 있습니다.어셈블러(assembler)를 예외로 하거나 다른 심각한 저수준 언어일 수도 있습니다.그러나 대부분의 중/고농도에는 표준 리브가 들어 있습니다.

Standard C 라이브러리는 ANSI C89/ISO C90의 일부입니다.이전에는 ANSI에 준거하지 않았던 C 컴파일러의 라이브러리 작업을 최근 실시하고 있습니다.

P.J. Plauger의 스탠다드 C Library는 그 프로젝트의 훌륭한 참고 자료였다.Plauger는 표준의 요건을 설명하는 것 외에 각 .h 파일의 이력과 API 설계의 이면에 있는 이유를 설명합니다.그는 또한 도서관의 완전한 구현도 제공해 주는데, 이것은 기준의 무언가가 명확하지 않을 때 저에게 큰 도움이 되었습니다.

이 규격은 15개의 헤더 파일 각각에 대한 매크로, 유형 및 함수를 기술하고 있습니다(stdio.h, stdlib.h, float.h, limits.h, math.h, local.h 등).

컴파일러는 표준 라이브러리를 포함하지 않는 한 ANSI C라고 주장할 수 없습니다.

어셈블리 언어에는 CPU, 메모리 및 기타 기본 기능의 레지스터로 값을 이동하고 기계의 핵심 기능과 계산을 수행하는 간단한 명령어가 있습니다.C 라이브러리는 기본적으로 어셈블리 코드의 청크입니다.C 프로그램에서 어셈블리 코드를 사용할 수도 있습니다.var는 어셈블리 코드 명령입니다.사용할 때0x숫자 앞에 16진수(조립 명령)를 붙입니다.어셈블리 코드는 기계 코드의 판독 가능한 형태로, 회로 경로의 실제 스위치 상태를 시각적으로 나타냅니다.

따라서 기계 코드, 즉 어셈블리 코드가 기계에 내장되어 있는 동안 C 언어는 어셈블리 언어 및 어셈블리 언어 또는 기타 C 라이브러리의 다른 함수를 호출할 수 있는 자체 함수를 포함하여 모든 종류의 미리 형성된 코드 조합으로 결합됩니다.어셈블리 코드는 모든 프로그래밍의 기초가 됩니다.그리고 그 이후에는 어떤 것이 어떤 것인지 추측할 수 있습니다.그렇기 때문에 많은 언어가 있고 진정한 기준이 거의 없는 것입니다.

언급URL : https://stackoverflow.com/questions/2572988/what-can-you-do-in-c-without-std-includes-are-they-part-of-c-or-just-libra

반응형