as i understand memory layout looks like the following:
jmp far F000:F900 (1)
-------------- ← FFFF:FFF0 processor startup address
— nothing—
-------------- ← F000:FFFF segment end
…
DefaultTable <-F000:F990+219 Default Table
…
some code
-------------- ← F000:F990 program startup (2)
— nothing—
-------------- ← F000:0000 segment start
so the following code should work fine:
…186
DATA_SEG = 0FF99h
code segment word public “CODE”
assume cs:code,ds:code
start:
; load data segment with program’s startup segment value
mov ax,DATA_SEG
mov ds,ax
mov bx,offset DefaultTable
mov ax,ds:[bx]
; some other code
; …
; some data
DefaultTable dw 1,2,3,4,5
code ends
end start
the idea is that address of data in segment : offset notation can be
presented in many ways. for example the absolute address of your DataTable
is 0xFF990 + 0x219 = .0xFFBA9. it can be accessed with 0xF000:0xFBA9
0xFF99:0x0219 0xFFBA:0x0009 and so on addresses. in your case you access it
defining cs: prefix → you rely on cs register value. cs register value
depends on where exactly you jumped from point (1). it can be “jmp far
0F000h:0FF90h” or it can be “jmp far 0FF99h:0000h” or many other variants.
so when you “access” your data with “mov bx, offset DefaultTable; mov
ax,cs:[bx]” in reallity you access any data withing segment space depending
on cs register vlaue set before by jump. note that assembler thinks that
offset of your data is relative to the beginning of assembled code if no
other assumptions made. so in order to write portable code and always be
sure you access right data there’s several variants:
-
address all data with default ds segment register. this also saves a
little of memory course directly specifying segment register differs to
default takes an additional byte for instructions. of course it requires
loading ds with correct value at startup as shown above. imho this is the
best choise.
-
if due to some reasons you need to access your data exactly with cs
segment register prefix you must load cs with correct value. or rather in
order to use “offset” assembler command you must be sure that cs is loaded
with value of the beginning of your assembled code. in your case this is
0FF99h. other way how does assembler know what additional values to add at
“offset DefaultTable” value which is relative to the beginning of assembled
code ? note that this case you are forced to load cs register at point (1)
with some predefined value → some loss of flexibility.
-
the worst variant: you can use assembler “org xxx” command. with this
command you can specify to assembler that your code/data is located at
additional xxx offset to the segment value. for example:
org 200h
start:
jmp near real_code
DataTable dw 1234h
real_code:
mov bx,[offset DataTable]
mov ax,cs:[bx]
…will place value 0202h in bx i.e. offset of DataTable related to the
beginning of program = 2 (jmp near takes 2 bytes) plus some predefined
offset for above case this is 200h. in general using this trick is not the
best idea course 1) you are forced to load your program at some fixed
address related to the segment value 2) for wasm offset specified at org
command cannot be larger that 0A00h. if it’s larger wasm just ignores it. so
anyway org wouldn’t help in your case.
ps: of course all above related only to x86 real mode.
pss: gas willn’t help you anyway. same troubles.
// wbr
“Dale Pischke” <dale@gyyr.com> wrote in message
news:9ainle$dm$1@inn.qnx.com…
Hi,
I’m writing a custom IPL for the STPC processor (486 architecture), and
have
a preliminary version working (actually boots and loads startup code).
However, I am having a assembly language problem, using wasm and wlink
(Watcom 6.1), and mkipl.
The processor resets to FFFFFFF0, where mkipl puts in a JMP instruction,
in
my case causing a jump to F000:F990 in real mode.
My program starts at offset F990, and boots fine.
When I try to access any tables in the IPL assembly code (memory
indirect),
the linker puts in the
wrong offset. For example, I have a table in the code segment,
named DefaultTable. I try to access the table as follows:
mov bx, OFFSET DefaultTable ; bx is 219, I want it to be
F990+
219
mov al, CS:[bx] ; returns data from
F000:0219, Default table really is at F000:(F990+219)
The offset loaded into bx is not what I would expect (F990 + offset to
DefaultTable). In this case, bx is 219h, which is the offset from the
beginning of my program (F990), treating reset as offset 0.
Am I missing something basic about real mode programming, or is OFFSET not
working properly with Watcom?
Thanks for any help on this, I am NOT an x86 assembly language guru.
Dale