내 C 프로그램의 전처리된 출력을 검사하던 중 우연히 헤더 파일을 보게 되었습니다.wordsize.h
그것은에 위치하고 있습니다
/usr/include/i386-linux-gnu/bits/wordsize.h
파일에 매크로가 하나만 포함되어 있습니다.
#define __WORDSIZE 32
내 질문은 단어 크기가 설치된 컴파일러에 의해 결정되는지, 아니면 내가 설치한 OS(32비트 또는 64비트)와 관련이 있는지, 아니면 내 하드웨어 구성과 관련이 있는지입니다. 기계.
저는 Linux에서 개발을 처음 접했습니다.
답변1
일반적으로wordsize
컴파일 시 대상 아키텍처에 따라 결정됩니다. 컴파일러는 일반적 wordsize
으로 현재 시스템을 사용하여 컴파일합니다.
(다른 것 중에서도) 다양한 플래그를 사용 gcc
하여 이를 조정할 수도 있습니다. 예를 들어 64비트 호스트에서는 컴파일할 수 있습니다.32비트기계, 또는힘32비트 단어.
-m32 # int, long and pointer to 32 bits, generates code for i386.
-m64 # int, long and pointer to 64 bits, generates code for x86-64.
-mx32 # int, long and pointer to 32 bits, generates code for x86-64.
또한 이 정의의 사용법을 살펴보고 확인해야 합니다 limits.h
.inttypes.h
크로스 컴파일 체크아웃의 경우멀티립(SO의 32비트 링크) 웹사이트를 검색해 보세요.
다음을 통해 GCC가 어떤 플래그로 빌드되었는지 확인하세요.
gcc -v
크기는 일반적으로 중앙 처리 장치와 밀접하게 관련되어 있으며 메모리 주소의 최대 크기, CPU 레지스터 크기 등과 관련됩니다.
간단히 살펴보기 위해 이 내용을 많이 이해할 필요는 없지만, 상황에 따라당신은 어디에그것은 약간의 통찰력을 줄 수 있습니다:
플래그를 사용 gcc
하고 컴파일 하면 -S
다음을 볼 수도 있습니다.조립 설명서. 여기서는 약간 혼란스럽습니다. 예를 들어 32비트 시스템에서는 단어가 16비트이고 긴 단어가 32비트입니다. ( __WORDSIZE
)
예를 들어 movl $123, %eax
장기 이동(32비트 - __WORDSIZE
) 을 의미합니다.123
eax
등록 하다, 및 movw
이동 단어(16비트)를 의미합니다.
이것은 명명 규칙입니다. 이는 WORDSIZE
한 가지 이상의 의미를 가질 수 있습니다. 예를 들어 다음과 같은 것을 정의하는 코드를 발견할 수도 있습니다.
#define WORD_SIZE 16
모든 것은 상황에 따라 달라지기 때문입니다. 소스의 워드 크기가 16비트인 파일이나 스트림에서 데이터를 읽는 경우 이는 자연스러운 일입니다. __WORDSIZE
코드에서 읽을 때 항상 단어 크기를 의미한다고 가정하지 않는다는 점을 지적하기 위한 것입니다 .
사용자 정의 예제는 WORD_SIZE
생성된 기계어 코드의 명령어 세트에 영향을 주지 않습니다. 일반적으로 GCC의 경우 권장합니다이 책.(불행히도 조금 오래되었지만 읽기 쉬운 최신 책을 아직 찾지 못했습니다. (그렇게 열심히 본 것은 아닙니다.) 짧고 간결하며 달콤합니다. 그리고 당신이 명심한다면 기능 추가 등 변경된 사항이 있을 수 있지만 그럼에도 불구하고 좋은 소개가 됩니다.)
컴파일할 때 다양한 측면을 빠르고 훌륭하게 소개합니다. 보다11장좋은 컴파일 체인 설명을 위해.
나는 16비트를 컴파일하기 위한 GCC의 어떤 옵션도 모릅니다. 이를 수행하는 한 가지 방법 .code16
은 코드가 16비트여야 함을 지시하기 위해 어셈블리로 작성하는 것입니다 .
예:
.file "hello.s"
.text
.code16 /* Tel GAS to use 16-bit instructions. */
.globl start, _start
start:
_start:
movb $0x48, %al
...
MBR
이는 하드 드라이브에 있는 코드에 대해 GRUB 및 LILO와 같은 부트 로더에 필요합니다 .
그 이유는 컴퓨터가 부팅될 때 CPU가 32비트가 아닌 최대 16비트 명령(AKA)을 갖는 특수 모드에 있기 때문입니다. 리얼 모드.
간단히 말해서 BIOS는 하드웨어 테스트를 수행한 다음 부팅 디스크의 처음 512바이트를 메모리에 로드하고 제어권은 address에서 시작하는 해당 코드에 남겨둡니다 0
. 이 코드는 차례로 파일의 다음 단계가 있는 위치를 찾아 이를 메모리에 로드하고 계속해서 실행합니다.
보호 모드당신이 어디에정상32비트 모드.
답변2
내 것은 다음과 같습니다.
% cat /usr/include/bits/wordsize.h
/* Determine the wordsize from the preprocessor defines. */
#if defined __x86_64__
# define __WORDSIZE 64
# define __WORDSIZE_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
wordsize.h
따라서 컴파일러와 함께 제공되는 에 의해 결정됩니다 . 그러나 지능적인 사람은 적절한 크기를 선택할 것입니다.
답변3
-m32
일반적으로 또는 옵션 중 하나를 사용하여 컴파일 시 기본 단어 크기를 선택할 수 있어야 합니다 -m64
.
/usr/include/i386-linux-gnu/bits/wordsize.h
32비트 응용 프로그램을 컴파일할 때 사용하도록 설계되었습니다.
/usr/include/x86_64-linux-gnu/bits/wordsize.h
64비트 정의가 포함 되어 있어야 합니다 __WORDSIZE
.
이 변경 사항은 Ubuntu 11.4에서 도입되었습니다.https://wiki.ubuntu.com/MultiarchSpec
실패 하면 -m64
32비트 배포판이 있을 수 있습니다. uname -m
당신에게 말할 것입니다.
32비트 시스템에서 64비트 바이너리를 크로스 컴파일하는 것이 가능하더라도 이를 실행할 수 있는 간단한 방법이 없기 때문에 불편할 것입니다.
CPU가 64비트 모델인 경우( 확인 lscpu
) 멀티아키 패키지를 쉽게 빌드할 수 있도록 64비트 배포판을 설치하는 것이 좋습니다.