이것은 무엇을 의미합니까?:*(int32 *) 0 = 0;
에서 다음코서에, 무이엇은 입니까?*(int32 *) 0 = 0;
비열한?
void
function (void)
{
...
for (;;)
*(int32 *) 0 = 0; /* What does this line do? */
}
몇 가지 참고 사항:
- 특정 코드 앞에 종료 문이 있기 때문에 코드에 연결할 수 없는 것 같습니다.
int32
이라typedef
하지만 당신은 그것에 너무 신경 쓰지 말아야 합니다.- 이 코드는 컴파일러의 언어 런타임에서 가져온 것으로, 관심 있는 사람이라면 누구나 사용할 수 있습니다.
코드는 다음을 수행합니다.
for (;;) // while(true)
*(int32 *) 0 = 0; // Treat 0 as an address, de-reference the 0 address and try and store 0 into it.
이것은 segfault, null 포인터 참조 취소가 되어야 합니다.
편집
추가 정보를 위해 컴파일 및 실행:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void){
*(int32_t *) 0 = 0;
printf("done\n");
return 0;
}
gcc -g null.c; ./a.out
Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cd in main () at null.c:7
7 *(int32_t *) 0 = 0;
OP는 이 코드가 숙련된 컴파일러 엔지니어에 의해 작성되었다고 언급하고 있으므로, 이것이 코드의 의도일 가능성이 있습니다.
*(int32 *) 0 = 0;
이 특정 C 구현에서 C 표준에 의해 정의되지 않은 동작을 유발하는 코드로 인식되며 이 구현에 알려진 동작은 불법입니다.- 그
for (;;)
또한 이 코드는 절대 종료되지 않음을 나타냅니다. - 컴파일러 엔지니어들은 옵티마이저가 이 코드를 인식하고 이 코드에 도달하는 모든 프로그램이 어떠한 동작도 허용되기 때문에 옵티마이저가 1코드에 도달하지 않는 것처럼 동작을 제공하도록 선택할 수 있기 때문에 옵티마이저가 이 코드를 "최적화되지 않은" 것으로 추론할 수 있다는 것을 알고 있습니다.
이러한 종류의 추론은 C 구현의 내부 작동에 대한 구체적인 지식이 있을 때만 가능합니다.이것은 컴파일러 엔지니어가 C 구현을 위한 특별한 헤더에 포함할 수 있는 종류이며, 아마도 특정 코드(예: 코드 뒤의 코드)를 표시하기 위해 포함할 수 있습니다.abort
통화)에 연결되지 않습니다.일반 프로그래밍에서는 절대 사용하면 안 됩니다.
1 예를 들어, 다음 코드를 생각해 보십시오.
if (a)
for (;;)
*(int 32 *) 0 = 0;
else
foo();
컴파일러는 당시 절이 모든 동작을 허용한다는 것을 인식할 수 있습니다.따라서 컴파일러는 어떤 동작을 가지고 있는지 자유롭게 선택할 수 있습니다.단순성을 위해 다음과 같은 동작을 하도록 선택합니다.foo();
그러면 코드는 다음과 같습니다.
if (a)
foo();
else
foo();
다음과 같이 더욱 단순화할 수 있습니다.
foo();
사실 이 코드 세그먼트 결함은 존재하는 이유를 설명하지 않습니다 =)
MCU의 런타임에서 나온 것 같습니다.프로그램 실행이 이 지점에 도달하면 해당 명령어가 MCU에 대한 소프트웨어 재설정을 시작하여 프로그램을 다시 시작하거나(임베디드 개발의 일반적인 관행) MCU가 하드웨어 워치독으로 구성된 경우 하드웨어 워치독으로 인해 강제로 MCU를 다시 시작하고 루프를 종료하지 않기 때문입니다.
이러한 구성의 주요 목표는 특정 작업을 시작하기 위해 OS 또는 하드웨어에서 처리할 수 있는 인터럽트를 호출하는 것입니다.
x86은 CPU 모드에 의존한다는 것을 알고 있습니다...Real Mode에서 watchdog가 없으면 실제로 즉시 아무 일도 일어나지 않습니다. 주소 0에는 'divide by 0' 핸들러의 주소가 있습니다. 따라서 일부 오래된 MS-DOS 또는 내장된 x86 런타임이면 'Divide by 0' 핸들러의 주소가 0으로 변경됩니다.따라서 이 인터럽트가 마스킹되지 않은 상태에서 발생하는 즉시 CPU는 위치 0:0으로 점프하여 잘못된 명령 때문에 다시 시작할 것입니다.보호 또는 VM x86 코드인 경우 OS 또는 다른 슈퍼바이저에 런타임에 문제가 있으며 소프트웨어를 외부에서 '제거'해야 함을 알리는 방법입니다.
for(;;)
는 와동합다니등다에 합니다.while(1)
,
*(int32 *) 0 = 0;
참조되지 않은 널 포인터에 0을 씁니다. 이는 충돌을 일으킬 것으로 예상되지만 실제로 특정 컴파일러에서는 항상 그렇지 않습니다. *(int*)로 스레드 충돌NULL = 1, 문제가 있습니까?
정의되지 않은 동작의 무한 루프입니다(null 포인터 참조).*n*x의 경우 segfault 또는 Windows의 경우 Access Violation으로 충돌할 가능성이 높습니다.
Mike의 의견은 꽤 정확합니다. 주소 0에 값 0을 저장하고 있습니다.
대부분의 기계에서 충돌이 일어날 것입니다.
원래 IBM PC는 가장 낮은 1KiB 메모리에 인터럽트 벡터 테이블을 저장했습니다.따라서 실제로 이러한 아키텍처의 주소 0에 32비트 값을 쓰는 것은 다음의 주소를 덮어씁니다.INT 00h
INT 00h는 PC에서 사용되지 않는 것처럼 보입니다.
기본적으로 현대적인 모든 것(x86/x86-64에서 보호 모드 또는 롱 모드로 실행되는 모든 것을 의미)에서는 사용자가 프로세스의 허용 주소 디레퍼런스 범위를 벗어나므로 링 0(커널 모드)에 있지 않는 한 분할 오류를 트리거합니다.
디레퍼런스는 정의되지 않은 동작이므로(이미 언급한 것처럼) 분할 결함은 이러한 상황을 처리하는 데 완벽하게 허용되는 방법입니다.대상 아키텍처에서 주소 참조가 0이면 분할 오류가 발생한다는 것을 알고 있다면 응용 프로그램을 중단시킬 수 있는 매우 확실한 방법인 것 같습니다.exit()
무언가가 끔찍하게 잘못되었기 때문에, 아마도 그것이 당신이 하고 싶은 것일 것입니다.코드가 특정 컴파일러의 런타임에서 가져온 것이라는 것은 코드를 작성한 사람이 컴파일러와 런타임의 내부 작동에 대한 지식을 활용할 수 있을 뿐만 아니라 특정 대상 아키텍처의 동작에 맞게 조정할 수 있다는 것을 의미합니다.
컴파일러가 모를 수 있습니다.exit()
반환되지 않지만 이 구조체가 반환되지 않는다는 것을 알고 있습니다.
언급URL : https://stackoverflow.com/questions/18407394/what-does-this-mean-int32-0-0
'programing' 카테고리의 다른 글
Oracle에서 오른쪽 괄호가 누락되었다고 생각하는 이유는 무엇입니까? (0) | 2023.08.04 |
---|---|
클래스 상수가 있는지 확인합니다. (0) | 2023.08.04 |
mysql의 그룹당 행 번호 (0) | 2023.08.04 |
하나의 항목을 Flexbox와 올바르게 정렬하려면 어떻게 해야 합니까? (0) | 2023.07.30 |
Angular2: 코어 모듈 대 공유 모듈 (0) | 2023.07.30 |