2013-01-09 59 views
5

Tôi đang cố gắng tìm hiểu cách tạo tệp .EXE bằng cách sử dụng assembly (NASM), xây dựng tiêu đề bằng tay và lắp ráp tệp dưới dạng nhị phân. Tôi gặp vấn đề với các tùy chọn trang (cả tổng số trang và số byte ở trang cuối cùng). Không có vấn đề làm thế nào nhỏ tôi thiết lập các giá trị ban đầu, chương trình sẽ làm việc.Tầm quan trọng của số trang và kích thước trang cuối cùng trong MZ (DOS, 16 bit) .EXE header

Là một trường hợp cực đoan, các chức năng chương trình sau đây ngay cả khi thiết lập 1 trang của 1 byte:

; 
; the smallest possible "Hello, World!" .EXE (DOS MZ) file 
; assemble with: 
; nasm -f bin -w+all -O0 smallest_hello_exe.asm -o ASM.EXE 
; 

bits 16 
cpu 8086 

; 
; by setting cs:ip=-10h:100h instead of 0h:0h inside the .EXE header 
; (identical assignments), we achieve the following two advantages: 
; 1) ds==cs, so no "push cs pop ds" is needed in order for ds:dx 
; to point to the message string 
; 2) we can exit by int 20h instead of int 21h, thus omitting the 
; ah=4ch assignment 
; (int 20h requires that cs points to the PSP segment) 
; 

; 
; we do not the address calculations to take the .EXE header into account 
; so we must subtract its length (20h) by an "org -20h" 
; but, since ip will be 100h, we must also issue an "org 100h" 
; and, since 0x100-0x20=0xE0... 

org 0xE0  ; 100h for ip value - 20h for header 



section .text align=1 
; 
; the MZ .EXE header structure 
; 28 bytes long 
; 1 pararaph equals 16 bytes 
; 1 page equals 512 bytes 
; suggested reading: int 21h,ah=4bh procedure 
; 
host_exe_header: 
.signature: dw 'MZ'  ; the 'MZ' characters 
.last_page_size: dw 1 ; number of used bytes in the final file page, 0 for all 
.page_count: dw 1  ; number of file pages including any last partial page 
.reloc: dw 0   ; number of relocation entries after the header 
.paragraphs: dw 2  ; size of header + relocation table, in paragraphs 
.minalloc: dw 0   ; minimum required additional memory, in paragraphs 
.maxalloc: dw 0xFFFF ; maximum memory to be allocated, in paragraphs 
.in_ss: dw 0   ; initial relative value of the stack segment 
.in_sp: dw 0xF000  ; initial sp value 
.checksum: dw 0   ; checksum: 1's complement of sum of all words 
.in_ip: dw 100h   ; initial ip value 
.in_cs: dw -10h   ; initial relative value of the text segment 
.offset: dw 0   ; offset of the relocation table from start of header 
.overlay: dw 0   ; overlay value (0h = main program) 

; pad header (its size in bytes must be a multiple of 16) 
times (32-$+$$) db 0 

mov dx,message 
mov ah,09h    ; write string ds:dx to stdout 
int 21h 
int 20h 

section .data align=1 
message: db 'Hello, World!$' 

section .bss align=1 

Thử nghiệm với kích thước chương trình khác nhau, tôi đã đi đến kết luận rằng Dos tải tất cả 512 byte của mỗi trang vào bộ nhớ. Nếu vậy, mục đích của số byte trong trang cuối cùng là gì?

Có thể ảnh hưởng đến phân bổ .bs, ngăn xếp dữ liệu và/hoặc bộ nhớ động không?

Trả lời

3

Tổng số trang chắc chắn không bị bỏ qua, nó thậm chí còn được sử dụng bởi các chương trình không muốn tất cả các tệp của họ được tải ban đầu. Họ sẽ đọc những mảnh cần thiết sau này. Trường bytes in the last page có thể hoặc không thể bỏ qua, tùy thuộc vào phiên bản hệ điều hành. Nó cũng có thể được làm tròn lên đến một đoạn hoặc ranh giới khu vực đĩa. Bạn không nên phụ thuộc vào một hành vi cụ thể và điền nó vào đúng.

Mã thử nghiệm của bạn hoạt động vì nó nhỏ và hệ điều hành cụ thể của bạn đã chọn tải đủ bộ nhớ vào bộ nhớ. Nếu bạn làm cho chương trình của mình lớn hơn một trang nhưng vẫn chỉ định 1 trong trường page count, có thể mã của bạn sẽ không được tải đầy đủ và sẽ không hoạt động. Tôi cố gắng:

times (32-$+$$) db 0 
times (512) nop 
mov dx,message 
mov ah,09h    ; write string ds:dx to stdout 
int 21h 
int 20h 

này thất bại nếu page count là 1, nhưng hoạt động nếu page count là 2 (sử dụng dosbox để thử nghiệm).

0

Trường số trang được sử dụng bởi DOS, không phải bởi Windows NT.

Hai trường duy nhất của IMAGE_DOS_HEADER được sử dụng bởi NT là e_magic (phải là IMAGE_DOS_SIGNATURE) và e_lfanew là giá trị nhỏ hơn 4MB từ đầu IMAGE_DOS_HEADER thành cấu trúc IMAGE_NT_HEADERS chứa tất cả thông tin cho trình tải NT .

Các vấn đề liên quan