Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

8086 rules - CS writing, lDebugX (Miscellaneous)

posted by ecm Homepage E-mail, Düsseldorf, Germany, 21.02.2024, 14:57

> > Writing to a code segment
>
> This also is configurable:
> https://en.wikipedia.org/wiki/Segment_descriptor
>
> As far as I remember, write-protected code segments became the default for
> Windows much later than Win9x, because app writers were used to overwriting
> code :-p

If you would reference the descriptor format you would notice that the "WR" bit means "writeable" for data descriptors but "readable" for code descriptors. You cannot execute from a data descriptor loaded as CS, only a code descriptor. So you cannot ever write with a cs: segment override prefix in Protected Mode, because CS must be loaded from a code descriptor and you cannot write to segments loaded from a code descriptor.

(Loading the selector in CS to another segment register will still load the code descriptor so even that doesn't suffice to write. You need a writeable data descriptor instead. This, of course, can have the same base as the code descriptor, aliasing the same memory.)

More generally on the topic of this thread, following the rules makes it easier to port a program to also run in Protected Mode. A good example is the original Debug/X as well as lDebug/X and its Extensions for lDebug. Most of their code is bimodal, it can run either in Real/Virtual 86 Mode or in a 16-bit CS in Protected Mode.

Following the rules in this case means not writing with the CS override / not using the selector in CS to try to write to the application's code segment. (Instead of pushing/moving CS to get the code segment into a data segreg, the original Debug/X was adjusted to push/mov SS instead. In lDebug/X this is needed in 86 Mode as well because even then SS != CS as we now use a stack/data/entry segment at another base address than the code segment(s).)

Also, using special purpose functions like setes2dx to address 86 Mode segments, which assembles to just mov es, dx in non-DPMI lDebug, but will set a scratch selector to address this 86 Mode segment while lDebugX is in PM. All segment arithmetic must be done using such filters and not depending on segregs holding Real Address Mode segment addresses. Some interrupt and function calls must go through Protected Mode int 31h functions to call down to the 86 Mode handlers. There are functions like selector_to_segment which must operate on a variable in memory or in a non-segreg register because segregs in PM can only hold valid selectors or 0000h. (This function will retrieve the segment base from the descriptor and return the 86 Mode segment that corresponds to this base. For this to be valid the selector must be referring to a 86 Mode segment base address, ie have a base of linear 0 to linear 0FFFF0h on a paragraph boundary.)

The AMIS common functions are easy to work with calling down from PM because they pass all segment values in non-segreg registers, so they need less special setup in the PM caller. For instance, the AMIS detection callout passes the segment in DX so the relatively simple call_int2D function can be used. In some of the AMIS private functions of lDebug I also followed this example. The notable exception is function 30h which consequently requires more setup to call from PM, involving the selector_to_segment function.

---
l

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 157 users online (0 registered, 157 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum