MZ 실행 파일
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
MZ 실행 파일은 도스(DOS) 운영체제에서 사용되는 실행 파일 형식이다. 이 파일 형식은 기본 머리(Header)와 재배치 정보(Relocation Table)로 구성되며, 파일의 속성과 실행에 필요한 정보를 담고 있다. 기본 머리에는 시그니처, 페이지 수, 재배치 항목 수, 머리 크기 등의 정보가 포함된다. MZ 실행 파일은 세그먼트 구조를 가지며, 코드, 데이터, 스택 세그먼트를 별도로 관리한다. MS-DOS 1.x 및 2.x API를 통해 프로그램 종료 방식을 제공하며, FASM 어셈블러를 사용하여 MZ 실행 파일을 생성할 수 있다. MZ 실행 파일은 DOS 및 윈도우 9x에서 실행 가능하며, 윈도우 NT 계열에서는 가상 도스 머신을 통해 실행할 수 있지만, 64비트 윈도우에서는 직접 실행이 불가능하다.
더 읽어볼만한 페이지
MZ 실행 파일 - [IT 관련 정보]에 관한 문서 | |
---|---|
파일 포맷 개요 | |
MIME 형식 | 해당 없음 |
uniform type identifier | 해당 없음 |
소유자 | 해당 없음 |
매직 넘버 | MZ 또는 ZM |
종류 | 바이너리, 실행 파일 |
컨테이너 포맷 | 해당 없음 |
포함 대상 | 해당 없음 |
확장 대상 | New Executable Linear Executable Portable Executable |
표준 | 해당 없음 |
2. 기본 구조
MZ 실행 파일은 기본 머리(Header)와 재배치 정보(Relocation Table)로 구성된다.
OFFSET | TYPE | 설명 |
---|---|---|
0000h | c char | MZ(0x4d, 0x5a) |
0002h | 1 word | 마지막 페이지(블록)의 바이트 수. (페이지 = 512바이트) |
0004h | 1 word | 파일의 총 페이지 수. |
0006h | 1 word | 재배치 항목의 수 |
0008h | 1 word | 단락 단위의 머리 크기. (단락 = 16바이트) |
000Ah | 1 word | 추가로 확보되어야 할 최소 단락 수 |
000Ch | 1 word | 추가로 확보되어야 할 최대 단락 수 (보통 65535, 1MB) |
000Eh | 1 word | 초기 SS (실행 시작 시점 기준) |
0010h | 1 word | 초기 SP |
0012h | 1 word | 실행 파일 체크섬 (또는 0) |
0014h | 1 word | 초기 IP (실행 시작 시점 기준) |
0016h | 1 word | 초기 CS (실행 시작 시점 기준) |
0018h | 1 word | 재배치 정보표의 시작 위치 (new-EXE: 40h) |
001Ah | 1 word | 오버레이 번호 (0h = 메인 프로그램) |
파일 크기는 16바이트 단락(Paragraph)과 512바이트 페이지 단위로 표현된다. 파일 전체 크기는 (pages - 1) * 512 + extrabytes로 계산되며, 머리와 재배치 정보도 포함된다.
COM 파일은 64KiB 내에서만 동작하므로 모든 주소가 명확하다. 메모리 위치와 관계없이 시작점을 세그먼트로 지정하면 실행에 문제가 없다.
MZ 형식은 64KiB 제한을 극복하고자 여러 세그먼트를 사용한다. 프로그램 실행 시점에 실제 메모리 위치를 알 수 없으므로, 0번지에 올려지는 것처럼 주소를 계산하고, 실제 로드 시 모든 세그먼트에 시작점을 더하는 재배치(Relocation)를 수행한다.
MZ 실행 파일은 재배치가 필요한 세그먼트 사용 위치를 재배치 표에 모아둔다. 도스는 프로그램을 로드할 때 재배치 표를 참조하여 실제 시작 주소(시작 세그먼트)를 더해준다.
재배치 표는 세그먼트가 사용된 주소(Segment:Offset)를 나열한다.
OFFSET | TYPE | 설명 |
---|---|---|
0000h | 1 word | 오프셋 |
0002h | 1 word | 재배치 세그먼트 |
재배치 항목은 Offset과 Segment (각 1 word, 총 4바이트)로 구성되며, 머리의 relocations 수만큼 존재한다.
2. 1. 기본 머리 (Header)
기본 머리(Header)는 파일의 속성과 실행에 필요한 정보를 담고 있다. 주요 필드로는 시그니처('MZ'), 파일 크기, 재배치 항목 수, 머리 크기, 최소/최대 메모리 요구량, 초기 스택 포인터(SP) 및 코드 세그먼트(CS) 값, 재배치 정보 위치 등이 있다.필드 | 설명 |
---|---|
signature | EXE 서명 (MZ 또는 ZM) |
extrabytes | 마지막 페이지의 바이트 수 |
pages | 파일 내 페이지 수 |
relocations | 파일 내 릴로케이션 수 |
headersize | 헤더 내 문단 수 |
minmemory | 최소 메모리 양 |
maxmemory | 최대 메모리 양 |
initSS | 초기 SS (실행 시작 시점 기준) |
initSP | 초기 SP |
checksum | 실행 파일 체크섬 (또는 0) |
initIP | 초기 IP (실행 시작 시점 기준) |
initCS | 초기 CS (실행 시작 시점 기준) |
reloctable | 재배치 정보표의 시작 위치 (40h는 new-(NE,LE,LX,W3,PE etc.) 실행 파일) |
overlay | 오버레이 번호 (0h = 메인 프로그램) |
파일 크기는 16바이트인 단락(Paragraph)과 512바이트인 페이지 단위로 표현한다. 파일 전체 크기는 (pages - 1) * 512 + extrabytes로 계산할 수 있으며, 여기에는 머리와 재배치 정보도 포함된다.
코드 부분이 페이지 단위로 정렬될 수 있도록 머리 크기를 페이지 단위로 맞추는 경우가 많다. 예를 들어 재배치 정보가 없더라도 headersize = 32 (32 * 16 = 512, 페이지 하나 크기)가 될 수 있다.
DOS에서 실행되는 EXE 프로그램 환경은 해당 프로그램의 프로그램 세그먼트 접두사에서 찾을 수 있다.
EXE 파일은 보통 코드, 데이터, 스택에 대해 별도 세그먼트를 가진다. 프로그램 실행은 코드 세그먼트 주소 0에서 시작하고, 스택 포인터 레지스터는 머리 정보에 포함된 값으로 설정된다. (머리가 512바이트 스택을 지정하면 스택 포인터는 200h) 별도 스택 세그먼트를 사용하지 않고 코드 세그먼트를 스택으로 사용할 수도 있다.
DS(데이터 세그먼트) 레지스터는 보통 CS(코드 세그먼트) 레지스터와 같은 값을 가지며, EXE 파일 초기화 시 데이터 세그먼트의 실제 세그먼트 주소로 로드되지 않는다. 프로그래머가 직접 설정해야 한다.
2. 2. 덧붙인 머리 (Extended Header)
다양한 개발 도구들이 MZ 형식의 기본 머리 뒤에 추가적인 정보를 덧붙여 사용하기도 한다. 마이크로소프트의 PE(Portable Executable) 형식도 MZ 형식을 기반으로 하므로, 덧붙인 머리에 PE 머리 정보를 포함한다. 다음은 MS SDK에 포함된 덧붙인 머리를 포함한 전체 머리 구조체의 예시이다.```c
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
```
앞 부분은 변수명만 다르게 정의되었을 뿐 기본 머리와 같다. PE에서 실질적인 의미가 있는 것은 맨 마지막의 e_lfanew 뿐이다. 새 형식의 머리가 어디에 있는지에 대한 정보다. 나머지 덧붙인 정보들은 PE가 만들어질 때까지 여러 제품들이 추가했던 정보들을 모두 반영하기 위한 형식적인 것이다.
2. 3. 재배치 정보 (Relocation Table)
재배치 정보는 프로그램이 메모리에 로드될 때 세그먼트 주소를 조정해야 하는 위치를 기록해 둔 표이다. 각 재배치 항목은 오프셋(Offset)과 세그먼트(Segment) 값으로 구성된다. 도스(DOS)는 프로그램을 메모리에 로드할 때 재배치 표를 참조하여, 프로그램 내에서 사용된 세그먼트 값들을 실제 로드된 주소에 맞게 수정한다.[1]MZ 형식은 여러 세그먼트를 가질 수 있도록 설계되었는데, 프로그램이 만들어질 당시에는 이 세그먼트들의 실제 메모리 위치를 알 수 없다. 따라서 프로그램은 자신이 0번지에 올려지는 것처럼 주소를 계산하고, 실제로 특정 메모리에 로드될 때 모든 세그먼트에 시작점을 더해주는 방식(재배치)을 사용한다.[1]
MZ 실행 파일은 재배치가 필요한 세그먼트가 사용된 위치를 모두 모아 재배치 표를 만든다. 도스는 프로그램을 메모리로 올릴 때, 재배치 표에 기록된 위치(프로그램에서 세그먼트가 사용된 곳)를 찾아 실제 프로그램이 시작하는 주소, 즉 시작 세그먼트를 더해준다.[1]
재배치 표는 프로그램에서 세그먼트가 사용된 곳의 주소(Segment:Offset)를 나열한 것이다. 재배치 항목 하나는 오프셋과 세그먼트가 각각 한 워드씩, 총 4바이트를 차지한다. 이러한 항목들이 머리(header)에 기록된 relocations 수만큼 존재한다.[1]
오프셋(OFFSET) | 타입(TYPE) | 설명 |
---|---|---|
0000h | 1 word | 오프셋 |
0002h | 1 word | 재배치 세그먼트 |
EXE 파일은 일반적으로 코드, 데이터, 스택 등 여러 세그먼트를 가진다. 프로그램 실행은 코드 세그먼트(CS)의 0번지에서 시작하며, 스택 포인터(SP) 레지스터는 헤더에 지정된 값으로 설정된다. 예를 들어, 헤더가 512바이트 스택을 지정하면 스택 포인터는 200h로 설정된다. 필요한 경우 별도의 스택 세그먼트를 사용하지 않고 코드 세그먼트를 스택으로 사용할 수도 있다.
MS-DOS 1.x API에서는 프로그램 종료 시 CS 레지스터가 PSP가 있는 세그먼트를 가리키도록 하고, RETF 명령어를 통해 종료했다.[1]
assembly
DOS가 실행하는 EXE 프로그램의 환경은 해당 프로그램의 프로그램 세그먼트 접두사에서 찾을 수 있다.[1]
3. 세그먼트 처리
데이터 세그먼트(DS) 레지스터는 보통 CS 레지스터와 같은 값을 가지며, EXE 파일이 초기화될 때 데이터 세그먼트의 실제 세그먼트 주소로 로드되지 않는다. 프로그래머가 직접 다음과 같은 명령을 통해 DS 레지스터를 설정해야 한다.[1]
MOV AX, @DATA
MOV DS, AX
4. 프로그램 종료
```nasm
PUSH DS
XOR AX, AX
PUSH AX
```
REFT 명령어는 스택에서 PSP가 있는 원래 세그먼트 주소를 가져와 주소 0으로 점프했는데, 주소 0에는 INT 20h 명령어가 있었다.[1]
MS-DOS 2.x API에서는 INT 21h Function 4Ch을 호출하여 프로그램을 종료하는 새로운 기능이 도입되었다.[1] 이 기능을 사용하면 프로그램 시작 시 PSP 세그먼트 주소를 저장할 필요가 없었으며, 마이크로소프트는 이전의 DOS 1.x 방식의 사용을 권장하지 않았다.[1]
5. FASM 예제
format MZ
entry _text:main
stack 80h
segment _text
main:
mov ax,_data
mov ds,ax
mov ah,9
mov dx,hello
int 21h
mov ax,4c00h
int 21h
segment _data
hello db 'Hello world!', 24h
```
FASM을 사용하면 이 프로그램은 77바이트의 아주 작은 MZ 실행 파일이 된다. 이 예제는 "Hello world!"를 출력하는 간단한 프로그램이다.
기본 머리 부분을 읽기 쉽게 바꾸면 다음과 같다.
```c
signature="MZ"
extrabytes=77
pages=1
relocations=1
headersize=2
minmemory=8
maxmemory=65535
initSS=3
initSP=128
checksum=0
initIP=0
initCS=0
reloctable=28
overlay=0
```
6. 호환성
MZ 실행 파일은 DOS와 윈도우 9x 계열의 운영 체제에서 실행된다. 32비트 윈도우 NT 계열에서도 가상 도스 머신을 통해 실행할 수 있지만, 일부 그래픽 모드는 지원되지 않는다. 64비트 윈도우에서는 실행할 수 없으며, DOSBox, DOSEMU, 와인 등의 에뮬레이터를 사용해야 한다.
디지털 마스 Optlink, MS 링커, VALX, 오픈 왓콤의 WLINK, FASM 등의 링커를 사용하여 MZ 실행 파일을 만들 수 있다.
참조
[1]
웹사이트
Inside Windows: An In-Depth Look into the Win32 Portable Executable File Format - MSDN Magazine, February 2002
https://msdn.microso[...]
2018-07-11
[2]
웹사이트
Inside Windows: An In-Depth Look into the Win32 Portable Executable File Format - MSDN Magazine, February 2002
https://msdn.microso[...]
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com