소형 elf "Hello, World" 프로그램
환경 요구: linux gcc nasm hexcurse (elf 파일 내용 수정 용)
먼저 C 언어 로 "Hello, World" 프로그램 을 써 보 세 요.
#include <stdio.h>
int main(void)
{
printf("Hello,World
");
return 0;
}
다음 명령 으로 컴 파일 하고 실행:
[host@myhost linker]$ gcc -o chello chello.c
[host@myhost linker]$ ./chello
출력 결과:
Hello,World
chello 의 ELF 헤드 부분 을 아래 명령 으로 볼 수 있 습 니 다.
readelf -h chello
출력 결과:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048310
Start of program headers: 52 (bytes into file)
Start of section headers: 1932 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 30
Section header string table index: 27
다음 명령 을 사용 하여 chello 링크 의 동적 링크 라 이브 러 리 를 봅 니 다:
ldd chello
출력 결 과 는:
linux-gate.so.1 => (0xb7857000)
libc.so.6 => /lib/libc.so.6 (0xb76d2000)
/lib/ld-linux.so.2 (0xb7858000)
다음 명령 으로 파일 형식 보기:
file chello
출력 결과:
chello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.27, not stripped
다음 명령 을 사용 하여 파일 크기 를 보고 strip 을 사용 하여 기호 표를 꺼 낸 다음 파일 크기 를 봅 니 다.
[host@myhost linker]$ ls -l chello
[host@myhost linker]$ strip -s chello
[host@myhost linker]$ ls -l chello
출력 결 과 는:
-rwxr-xr-x 1 host users 4746 11 6 23:07 chello
-rwxr-xr-x 1 host users 3036 11 6 23:15 chello
다음은 어 셈 블 리 코드 를 사용 하여 이 프로그램 (hello. asm) 을 작성 하고 Liux 인 터 럽 트 를 호출 합 니 다.
SECTION .data
msg: db "Hello,World",10
len: equ $-msg
SECTION .text
global main
main:
mov edx,len
mov ecx,msg
mov ebx,1
mov eax,4
int 0x80
mov ebx,0
mov eax,1
int 0x80
다음 명령 으로 링크 를 컴 파일 하고 파일 을 만 드 는 기호 표를 꺼 냅 니 다:
[host@myhost linker]$ nasm -f elf hello.asm
[host@myhost linker]$ gcc -o hello hello.o -nostartfiles -nostdlib -nodefaultlibs
[host@myhost linker]$ strip -s hello
[host@myhost linker]$ ./hello
출력 결 과 는:
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 08048080
Hello,World
gcc 명령 을 사용 할 때 경고 가 발생 하지만 이 파일 은 실행 할 수 있 습 니 다. 이 파일 의 크기 는 360 바이트 입 니 다.
"gcc - o hello hello. o - nostartfiles - nostdlib - nodefaultlibs" 명령 을 연결 합 니 다. 영어 주석 은 다음 과 같 습 니 다 링크.
-nostartfiles
Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used.
-nodefaultlibs
Do not use the standard system libraries when linking. Only the libraries you specify will be passed to the linker, options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, will be ignored. The standard startup files are used normally, unless -nostartfiles is used. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
-nostdlib
Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify will be passed to the linker, options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, will be ignored. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
One of the standard libraries bypassed by -nostdlib and -nodefaultlibs is libgcc.a, a library of internal subroutines that GCC uses to overcome shortcomings of particular machines, or special needs for some languages. (See Interfacing to GCC Output, for more discussion of libgcc.a.) In most cases, you need libgcc.a even when you want to avoid other standard libraries. In other words, when you specify -nostdlib or -nodefaultlibs you should usually specify -lgcc as well. This ensures that you have no unresolved references to internal GCC library subroutines. (For example, `__main', used to ensure C++ constructors will be called;
여기 startupfiles 는 crt0. o (/ lib / crt0. o), crtbegin. o, crtend. o 를 말 합 니 다. crt0. o 는 main 함수 (windows 에서 WinMainCRTStartup 참조 링크 를 호출 하 는 코드 를 포함 하고 있다 고 합 니 다. 여 기 는 어 셈 블 리 코드 를 사용 합 니 다.(c 프로그램 이 라면 crt0. o 를 연결 해 야 합 니 다) 따라서 crt0. o. crtbgin. o 와 crtend. o 를 연결 하지 않 아 도 됩 니 다. c + 구조 와 석조 함 수 를 처리 하 는 데 사용 된다 고 합 니 다. main 함수 로 c 프로그램 을 만 들 지 않 는 다 는 댓 글 Is main required for a c program? 이 있 습 니 다.(사실은 입구 이름 을 바 꾸 는 것 일 뿐 입 니 다. Window 응용 프로그램 이 WinMain 을 입구 함수 로 사용 하 는 것 처럼 자신의 입구 함수 만 사용 할 뿐 관련 처 리 는 모두 스스로 해결 해 야 합 니 다)
다음 명령 을 사용 하여 hello 의 16 진수 설명 을 받 습 니 다:
hexdump -x hello
출력 결과:
0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0002 0003 0001 0000 8080 0804 0034 0000
0000020 00c8 0000 0000 0000 0034 0020 0002 0028
0000030 0004 0003 0001 0000 0000 0000 8000 0804
0000040 8000 0804 00a2 0000 00a2 0000 0005 0000
0000050 1000 0000 0001 0000 00a4 0000 90a4 0804
0000060 90a4 0804 000c 0000 000c 0000 0006 0000
0000070 1000 0000 0000 0000 0000 0000 0000 0000
0000080 0cba 0000 b900 90a4 0804 01bb 0000 b800
0000090 0004 0000 80cd 00bb 0000 b800 0001 0000
00000a0 80cd 0000 6548 6c6c 2c6f 6f57 6c72 0a64
00000b0 2e00 6873 7473 7472 6261 2e00 6574 7478
00000c0 2e00 6164 6174 0000 0000 0000 0000 0000
00000d0 0000 0000 0000 0000 0000 0000 0000 0000
*
00000f0 000b 0000 0001 0000 0006 0000 8080 0804
0000100 0080 0000 0022 0000 0000 0000 0000 0000
0000110 0010 0000 0000 0000 0011 0000 0001 0000
0000120 0003 0000 90a4 0804 00a4 0000 000c 0000
0000130 0000 0000 0000 0000 0004 0000 0000 0000
0000140 0001 0000 0003 0000 0000 0000 0000 0000
0000150 00b0 0000 0017 0000 0000 0000 0000 0000
0000160 0001 0000 0000 0000
이 파일 헤더 (앞의 52 바이트) 를 분석 하면 두 개의 비교적 중요 한 표 의 내용 을 알 수 있다. 첫 번 째 는 프로그램 헤더 (54 (0x 34) 개의 바이트 가 시작 되 고 크기 는 2 * 32 (0x 20) 개의 바이트) 이 며, 다른 하 나 는 세그먼트 헤드 시트 (200 (0xc 8) 개의 바이트 가 시작 되 고 크기 는 2 * 40 (0x 28) 개의 바이트 이다. 그리고 세그먼트 헤드 시트 에 따라 코드 세그먼트 (0x 80 시작 34 바이트 내용) 를 알 수 있다.데이터 세그먼트 (0xa 4 부터 12 바이트 내용) 와 관련 된 정보 입 니 다. 중요 한 것 은 앞의 176 바이트 내용 입 니 다. 이 부분 은 파일 헤더 (52 바이트), 프로그램 헤더 시트 (64 바이트), 공백 내용 (12 바이트), 코드 세그먼트 (34 바이트), 데이터 세그먼트 (12 바이트, Hello, World) 로 나 눌 수 있 습 니 다.
다음 명령 을 사용 하여 hello 의 이전 176 바이트 내용 을 추출 할 수 있 는 권한 을 실행 할 수 있 습 니 다.
dd if=hello of=hello.new bs=176 count=1
chmod u+x hello.new
파일 hello. new 를 가 져 옵 니 다. 이 파일 을 실행 하면 "Hello, World" 를 얻 을 수 있 습 니 다. 이 파일 은 바 이 너 리 내용 입 니 다.
0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0002 0003 0001 0000 8080 0804 0034 0000
0000020 00c8 0000 0000 0000 0034 0020 0002 0028
0000030 0004 0003 0001 0000 0000 0000 8000 0804
0000040 8000 0804 00a2 0000 00a2 0000 0005 0000
0000050 1000 0000 0001 0000 00a4 0000 90a4 0804
0000060 90a4 0804 000c 0000 000c 0000 0006 0000
0000070 1000 0000 0000 0000 0000 0000 0000 0000
0000080 0cba 0000 b900 90a4 0804 01bb 0000 b800
0000090 0004 0000 80cd 00bb 0000 b800 0001 0000
00000a0 80cd 0000 6548 6c6c 2c6f 6f57 6c72 0a64
데이터 세그먼트 크기 가 딱 12 이 고 파일 에 12 개의 바이트 공백 이 있 기 때문에 데이터 세그먼트 (0xa 4 에서 시작 하 는 12 개의 글자 분해) 를 공백 으로 옮 길 수 있 습 니 다 (0x 74 에서 시작 하 는 12 개의 바이트)., 0x 86 주소 의 0xa 4 를 0x 74 로 변경 합 니 다. hexcurse hello. new 를 사용 하여 파일 내용 을 수정 한 다음 단축 키 crtl + s 로 저장 하고 hello. res 로 이름 을 바 꿀 수 있 습 니 다. 이 때 hello. res 를 실행 하면 "Hello, World" 를 얻 을 수 있 습 니 다.
그리고 마지막 12 개의 바이트 (명령 dd if = hello. res of = hello. out bs = 164 count = 1) 를 삭제 하고 hello. out 이 마지막 인 결 과 를 얻 을 수 있 습 니 다. 크기 는 164 개의 바이트 입 니 다. 원문 에 따 르 면 이 파일 은 더 압축 할 수 있 지만 코드 세그먼트 의 일부분 을 변경 하고 시간 이 있 을 때 자세히 연구 해 야 합 니 다)
Why are DJGPP .exe files so large?
파일 헤더 에는 e entry (0x 18 주소 로 시 작 된 4 개의 바이트 가 있 습 니 다. 값 은 0x 08048080 (0x 08048000 + 0x 80 (코드 세그먼트 오프셋 주소) 입 니 다. 이 주소 에서 명령 을 실행 하 는 것 입 니 다. 코드 세그먼트 (0x 86 에서 시 작 된 4 개의 바이트 (작은 단 법 표시, 9074 0804) 즉 0x 08049074 입 니 다. 이 주 소 는 0x 08048000 + 0x 1000 입 니 다.(코드 세그먼트 가상 주소 가 차지 하 는 공간 크기 는 세그먼트 정렬 이 0x 1000 이기 때문에 최소 4k 크기 (페이지 시스템 에서 각 페이지 의 크기) + 0x 74 입 니 다. 이 주 소 는 원래 주소 0x 080490 a4 입 니 다.(이 주 소 는 원래 의 0x0000005c 와 0x000000060 에서 시 작 된 4 개의 바이트 에 각각 존재 합 니 다. 그러나 0x0000005c 와 0x000000060 의 값 은 업 종 을 바 꾸 지 않 고 정상적으로 작 동 할 수 있 는 것 같 지만 데 이 터 를 일치 시 키 기 위해 서 는 고 치 는 것 이 좋 습 니 다.)
또한 hello. out 은 ELF 헤드, 프로그램 헤드, 코드 세그먼트 와 데이터 세그먼트 만 포함 하고 정상적으로 작 동 할 수 있 으 며 실행 가능 한 파일 중간 헤더 표 (section Header table) 가 옵션 임 을 증명 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Hibernate의 Annotation 버전 Hello world 인스턴스본고는 Hibernate의 Annotation 버전인 Hello world의 실현 방법을 실례로 다루고 있다.다음과 같이 여러분에게 참고할 수 있도록 공유합니다. 도입해야 할 가방:hibernate-commons-a...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.