C 프로그램의 전처리된 출력을 확인하던 중 우연히 헤더 파일을 보게 되었습니다.wordsize.h
위치해있습니다
/usr/include/i386-linux-gnu/bits/wordsize.h
파일에 매크로가 하나만 포함되어 있습니다.
#define __WORDSIZE 32
내 질문은 단어 길이가 설치된 컴파일러에 의해 결정되는지, 아니면 내가 설치한 운영 체제(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 레지스터 크기 등과 같이 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바이트를 메모리에 로드하고 제어권은 주소에서 시작하는 코드에 맡깁니다 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비트 배포판을 설치해야 할 수도 있습니다.