Remix.run Logo
smitelli 2 days ago

Scenario A: Picture that a quick, tiny function is needed that can load data from struct members and operate on them. The structs are tiny but there are a whole lot of them, and the values of interest always start at offsets e.g. 0, 4, and 8. If the structs can be stored in memory aligned on a segment boundary, a pointer can be constructed where offset 0 always points to the beginning of the struct, and the code can use the literal offsets 0, 4, 8 added to the pointer base without having to do any further arithmetic.

Scenario B: Imagine you're writing a page of video to the VGA framebuffer. Glossing over a whole lot of minutiae, you can simply jam 64,000 bytes into the address and data lines starting at A000:0000 without needing to stop and think about what you're doing w.r.t. the segment registers. Any kind of segment change every n bytes would require the loop to be interrupted some number of times over the course of the transfer to update DS or ES. This would also prevent something like `rep movs` from being able to work on a full screenful of data.

The 16-byte paragraph, and the many segment/offset aliases that could be constructed to refer to a single linear memory address, was a design choice that tried to serve the needs of both of those groups.