Struct Header

Source
#[repr(C)]
pub struct Header {
Show 14 fields pub magic: [u8; 2], pub cblp: Integer<LittleEndian<u16>, AlignAs<2>>, pub cp: Integer<LittleEndian<u16>, AlignAs<2>>, pub crlc: Integer<LittleEndian<u16>, AlignAs<2>>, pub cparhdr: Integer<LittleEndian<u16>, AlignAs<2>>, pub minalloc: Integer<LittleEndian<u16>, AlignAs<2>>, pub maxalloc: Integer<LittleEndian<u16>, AlignAs<2>>, pub ss: Integer<LittleEndian<u16>, AlignAs<2>>, pub sp: Integer<LittleEndian<u16>, AlignAs<2>>, pub csum: Integer<LittleEndian<u16>, AlignAs<2>>, pub ip: Integer<LittleEndian<u16>, AlignAs<2>>, pub cs: Integer<LittleEndian<u16>, AlignAs<2>>, pub lfarlc: Integer<LittleEndian<u16>, AlignAs<2>>, pub ovno: Integer<LittleEndian<u16>, AlignAs<2>>,
}
Expand description

File Header

This static structure is located at offset 0 of a DOS MZ executable. It has a fixed size of 28 bytes and describes the further layout of the file.

Fields§

§magic: [u8; 2]

The static signature identifying the file-format. This must match MAGIC. (abbr: magic-identifier).

§cblp: Integer<LittleEndian<u16>, AlignAs<2>>

The number of bytes in the last page of the program (abbr: count-bytes-last-page)

While cp describes the number of pages that make up this executable, this cblp field describes the number of valid bytes in the last page. The special value of 0 denotes the entire last page as part of the executable.

Any other data beyond this offset is ignored. It is valid to append data for other reasons to the end of the file.

§cp: Integer<LittleEndian<u16>, AlignAs<2>>

The number of pages of this program (abbr: count-pages)

This is the absolute number of pages starting from the beginning of the header that make up this executable. Any data beyond this is ignored. The cblp field describes how many bytes of the last page are actually part of the program.

E.g., A cp of 2 with cblp of 16 means (2-1)*512+16=528 bytes. A cp of 3 with cblp of 0 means 3*512=1536 bytes.

§crlc: Integer<LittleEndian<u16>, AlignAs<2>>

The number of relocations in the relocation header (abbr: count-re-lo-cations)

In combination with lfarlc this describes the location and size of the relocation table. The crlc field is the number of relocation entries in this table. See lfarlc for details.

§cparhdr: Integer<LittleEndian<u16>, AlignAs<2>>

The number of paragraphs that make up the header (abbr: count-paragraphs-header).

§minalloc: Integer<LittleEndian<u16>, AlignAs<2>>

The minimum number of additional paragraphs required for program execution (abbr: minimum-allocation).

When a program is loaded into memory, its program size is the file size as specified by cp and cblp minus the size of the header as specified by cparhdr. This size is then extended by minalloc to calculate the minimum amount of memory required to execute the program.

This technique allows linkers to strip uninitialized static variables from the program code, and thus reduce the size of the file. The variables are then located in the allocated space trailing the program code, and thus still available at runtime.

§maxalloc: Integer<LittleEndian<u16>, AlignAs<2>>

The maximum number of additional paragraphs required for program execution (abbr: maximum-allocation).

While minalloc is a minimum requirement to allow execution of a program, maxalloc specifies how much more memory the application would like allocated. The OS is free to allocate more or less. The PSP contains information about how much was actually allocated.

maxalloc cannot be less than minalloc, or it will be ignored.

A value of 0xffff simply means to allocate as much memory as possible. The application is still free to use MS-DOS software interrupts to deallocate memory again.

§ss: Integer<LittleEndian<u16>, AlignAs<2>>

The initial stack-segment offset to use (abbr: stack-segment).

The stack-segment register is set to the same value as the code-segment register at program start. The latter is set to the first segment of the program loaded in memory. In front of this first segment is usually the PSP (the DS and ES registers contain the segment of the PSP at program start, to avoid relying on this).

This ss value is an offset added to the stack-segment register at program start, and thus allows moving the stack into later segments.

§sp: Integer<LittleEndian<u16>, AlignAs<2>>

The initial stack pointer to use (abbr: stack-pointer).

This specifies the initial value of the sp register. In combination with ss it defines the start of the stack. In most cases, this value is set to 0, since this will cause the first stack push to overflow the value and thus push at the end of the stack segment.

§csum: Integer<LittleEndian<u16>, AlignAs<2>>

The checksum of the file (abbr: check-sum).

The checksum of the file is the one’s complement of the summation of all words of the file (with csum set to 0). Note that this only applies to the data as specified by cp and cblp. Any trailing data is ignored. If cblp is odd, the last byte trailing it must be assumed to be 0, even if other data is trailing it.

The checksum is calculated as little-endian sum of all 16-bit integers that make up the file.

§ip: Integer<LittleEndian<u16>, AlignAs<2>>

The initial instruction pointer to use (abbr: instruction-pointer).

This is the initial value of the instruction pointer register ip. Since it is relative to the code-segment register cs, this value is taken verbatim by the loader.

§cs: Integer<LittleEndian<u16>, AlignAs<2>>

The initial code segment offset to use (abbr: code-segment).

Similar to the stack-segment register ss, this value defines the offset to apply to the code-segment register cs before executing the code. The actual value before the offset is applied is the first segment the program was loaded into.

§lfarlc: Integer<LittleEndian<u16>, AlignAs<2>>

The absolute offset to the relocation table (abbr: logical-file-address-re-lo-cation).

This is the offset of the relocation table relative to the start of the header (and thus usually the start of the file). The relocation table is an array of relocations (see Relocation). The number of entries is specified in crlc.

The relocation table is usually trailing the static header and included in the size of the header. However, an application is free to place the table at any other offset.

The size of the static header plus the extension header is 0x40, hence a relocation table offset of 0x40 usually designates the existance of an extension header (yet this is not a requirement). The extension header still needs its own signature verification to ensure its validity.

§ovno: Integer<LittleEndian<u16>, AlignAs<2>>

The overlay number (abbr: overlay-number).

This is 0 if the file is not an overlay. Otherwise, this specifies the overlay index to assign.

Overlays are used to reserve programs but avoid loading them into memory. See the MS-DOS overlay support for details. For any regular application, this is set to 0.

Implementations§

Source§

impl Header

Source

pub fn from_bytes(data: &[u8; 28]) -> Self

Import a header from a byte slice

Create a new header structure from a byte slice, copying the data over. The data is copied verbatim without any conversion.

Source

pub fn as_bytes(&self) -> &[u8; 28]

Convert to byte slice

Return a byte-slice reference to the header. This can be used to export the structure into a file. No byte-order conversions are applied.

Auto Trait Implementations§

§

impl Freeze for Header

§

impl RefUnwindSafe for Header

§

impl Send for Header

§

impl Sync for Header

§

impl Unpin for Header

§

impl UnwindSafe for Header

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.