Before starting a new bug ticket, I wanted to make sure this isn't a programmer's mistake.
I am currently experimenting with protected mode and went for full segment definitions with JWasm. At a certain point I noticed that some segments were overlapping, i.e. the first 16 bytes of segment Y overlapped with the last 16 bytes of preceding segment X. In my case, this means my primary TSS is overlapping with output messages for my exception handlers. On top of that, although I explicitly tell the assembler to initialize my TSS structure to zero, the first 16 bytes are overwritten with said text. Enough said.
The text segment is defined as:
_TEXT SEGMENT BYTE PUBLIC 'TEXT'
_TSS0 SEGMENT PARA PUBLIC 'TSS' ; with the idea of grouping all TSSes later
_TEXT is referenced multiple times in text generating macros, also in other object files.
After hours and hours of fruitless effort, I still couldn't fix anything, except move my data to an existing segment, but I did not want this (and who knows maybe I hit a bug). This includes making all segments private.
So I tried to make a minimal code example and figure it out:
* CODE SNIPPET *
.286
_DATA1 SEGMENT PARA PRIVATE 'DATA'
msg_data1 db '_DATA1 _DATA1 _DATA1 _DATA1 _DATA1 _DATA1 _DATA1 _DATA1'
_DATA1 ENDS
_DATA2 SEGMENT PARA PRIVATE 'DATA2'
msg_data2 db '_DATA2 _DATA2 _DATA2 _DATA2 _DATA2 _DATA2 _DATA2 _DATA2'
_DATA2 ENDS
_CODE SEGMENT WORD PUBLIC 'CODE'
Start: mov ax,_DATA1
mov ax,_DATA2
mov ax,4c00h
int 21h
_CODE ENDS
END Start * END OF CODE SNIPPET *
Now, assembling and linking this with ML.EXE produces the perfect result: private segments, ergo different segment addresses.
Assembling it with MASM.EXE or JWASMD.EXE and then linking with JWLINKD.EXE or WLINK.EXE did not. It appears both segments are mapped to the same segment address, as seen here:
* DEBUGGER SNIPPET *
cs:0008 mov ax,164E
cs:000B mov ax,164E
* END OF DEBUGGER SNIPPET *
At first glance this seems another issue, but I'm not 100% sure.
The command line used to link the object file was:
JWLINKD format dos file test.obj name test.exe
I used the version I downloaded just now from the website. I'm also aware of the STACK modifier problem, but this seems unrelated.
EDIT: Assembling and linking my protected mode program with ML also produces de correct result.
Last edit: Diederik Huys 2012-10-10
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK New info for my first problem:
The problem is arising with multiple object files.
I checked also the offsets to the TSS structure.
Linker
Segment
Offset
LA
ML.EXE
1682h
0
16820h
JWLINKD
1671h
8
16718h
I added the source code in attachment. The code has been stripped for clarity, also here and there zero's have been replaced by filler bytes to easily see it in a debugger session.
I tested with MS link (OMF) and jwlink. There are a few differences, but I see no problem - AFAICS there's no "overlapping" of segments.
I created map files with both linkers. The segments are in exactly the same order. MS link's executable has a header size of 0x200, while the one created by jwlink has just the minimum of 0x40.
The segments are:
_DATA DATA DGROUP 0000:0000 00000010
_TEXT DATA DGROUP 0001:0000 00000227
_TSS0 TSS AUTO 0023:0008 00000032
_STACK STACK AUTO 0027:0000 00000400
_STACK3 AUTO 0067:0000 00000400
_CODE CODE AUTO 00a7:0000 00000074
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have to admit that I assumed that the start of TSS within segment _TSS0 is zero. When I add a line "mov ax,OFFSET TSS" then with the MS linker I get 0 and with JWLINK I get 8. This is in accordance with the MAP files and indeed both point to the same offset within the executable. But I'd assume that the start of any data or code within a new segment would be zero (as is the case with MS LINK), especially with different segment and class identifiers.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
But I'd assume that the start of any data or code within a new segment would be zero (as
is the case with MS LINK), especially with different segment and class identifiers.
AFAIK segment alignment is not affected by class ids. You'll have to set alignment of _TSS to PARA if you want the segment to start at a new "paragraph".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I see. I realize my error now. I was confused with the fact that address = segment * 10h. It also explains why most people only use "PARA" alignment I suppose ;)
Thanks for the help!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I changed the TSS segment in the code example to alignment 'PARA', but now I noticed this:
Segment Class Group Address Size
======= ===== ===== ======= ====
_DATA DATA DGROUP 0000:0000 00000010
_TEXT DATA DGROUP 0001:0000 00000227
_TSS0 TSS AUTO 0024:0000 00000032
_STACK STACK AUTO 0024:0040 00000400
_STACK3 AUTO 0068:0000 00000400
_CODE CODE AUTO 00a8:0000 000000a4
I don't understand why, by changing the alignment of _TSS0, suddenly the _STACK segment value is fused with _TSS0 and the difference is left in the offset part (debugging this session shows SP=440h). Very confusing.
(With WORD alignment, I get of course the same result as the map file you posted).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I don't understand why, by changing the alignment of _TSS0, suddenly the _STACK segment > value is fused with _TSS0 and the difference is left in the offset part
Yes, the "auto-packing" of segments is annoying. This most likely will be changed. For now, as a work-around, try linker option PACKDATA=0.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
Before starting a new bug ticket, I wanted to make sure this isn't a programmer's mistake.
I am currently experimenting with protected mode and went for full segment definitions with JWasm. At a certain point I noticed that some segments were overlapping, i.e. the first 16 bytes of segment Y overlapped with the last 16 bytes of preceding segment X. In my case, this means my primary TSS is overlapping with output messages for my exception handlers. On top of that, although I explicitly tell the assembler to initialize my TSS structure to zero, the first 16 bytes are overwritten with said text. Enough said.
The text segment is defined as:
_TEXT SEGMENT BYTE PUBLIC 'TEXT'
_TSS0 SEGMENT PARA PUBLIC 'TSS' ; with the idea of grouping all TSSes later
_TEXT is referenced multiple times in text generating macros, also in other object files.
After hours and hours of fruitless effort, I still couldn't fix anything, except move my data to an existing segment, but I did not want this (and who knows maybe I hit a bug). This includes making all segments private.
So I tried to make a minimal code example and figure it out:
* CODE SNIPPET *
_DATA1 SEGMENT PARA PRIVATE 'DATA'
msg_data1 db '_DATA1 _DATA1 _DATA1 _DATA1 _DATA1 _DATA1 _DATA1 _DATA1'
_DATA1 ENDS
_DATA2 SEGMENT PARA PRIVATE 'DATA2'
msg_data2 db '_DATA2 _DATA2 _DATA2 _DATA2 _DATA2 _DATA2 _DATA2 _DATA2'
_DATA2 ENDS
_CODE SEGMENT WORD PUBLIC 'CODE'
Start: mov ax,_DATA1
mov ax,_DATA2
mov ax,4c00h
int 21h
_CODE ENDS
END Start
* END OF CODE SNIPPET *
Now, assembling and linking this with ML.EXE produces the perfect result: private segments, ergo different segment addresses.
Assembling it with MASM.EXE or JWASMD.EXE and then linking with JWLINKD.EXE or WLINK.EXE did not. It appears both segments are mapped to the same segment address, as seen here:
* DEBUGGER SNIPPET *
cs:0008 mov ax,164E
cs:000B mov ax,164E
* END OF DEBUGGER SNIPPET *
At first glance this seems another issue, but I'm not 100% sure.
The command line used to link the object file was:
JWLINKD format dos file test.obj name test.exe
I used the version I downloaded just now from the website. I'm also aware of the STACK modifier problem, but this seems unrelated.
EDIT: Assembling and linking my protected mode program with ML also produces de correct result.
Last edit: Diederik Huys 2012-10-10
OK New info for my first problem:
The problem is arising with multiple object files.
I checked also the offsets to the TSS structure.
I added the source code in attachment. The code has been stripped for clarity, also here and there zero's have been replaced by filler bytes to easily see it in a debugger session.
Last edit: Diederik Huys 2012-10-10
I tested with MS link (OMF) and jwlink. There are a few differences, but I see no problem - AFAICS there's no "overlapping" of segments.
I created map files with both linkers. The segments are in exactly the same order. MS link's executable has a header size of 0x200, while the one created by jwlink has just the minimum of 0x40.
The segments are:
OTOH, this is what MS link map-file tells:
I have to admit that I assumed that the start of TSS within segment _TSS0 is zero. When I add a line "mov ax,OFFSET TSS" then with the MS linker I get 0 and with JWLINK I get 8. This is in accordance with the MAP files and indeed both point to the same offset within the executable. But I'd assume that the start of any data or code within a new segment would be zero (as is the case with MS LINK), especially with different segment and class identifiers.
AFAIK segment alignment is not affected by class ids. You'll have to set alignment of _TSS to PARA if you want the segment to start at a new "paragraph".
I see. I realize my error now. I was confused with the fact that address = segment * 10h. It also explains why most people only use "PARA" alignment I suppose ;)
Thanks for the help!
Wait a minute,
I changed the TSS segment in the code example to alignment 'PARA', but now I noticed this:
I don't understand why, by changing the alignment of _TSS0, suddenly the _STACK segment value is fused with _TSS0 and the difference is left in the offset part (debugging this session shows SP=440h). Very confusing.
(With WORD alignment, I get of course the same result as the map file you posted).
Yes, the "auto-packing" of segments is annoying. This most likely will be changed. For now, as a work-around, try linker option PACKDATA=0.
Yes, that was the problem. It works now! Thanks!