Okay, this is driving me nuts. Several of John Fine's code does this with no problem, but I always get an error from NASM saying that "shift operater can only be used on scalar values". A snippet of my code is posted below.
[tt]
[SECTION .data]
[global _tss0_begin]
_tss0_begin: ;empty, this is just so that we can "get the ball rolling"
dw 0 ; back link
dd 0 ; esp0
dw 0 ; ss0
dd 0 ; esp1
dw 0 ; ss1
dd 0 ; esp2
dw 0 ; ss2
dd 0 ; cr3
dd 0 ; eip
dd 0 ; eflags
dd 0 ; eax
dd 0 ; ecx
dd 0 ; edx
dd 0 ; ebx
dd 0 ; esp
dd 0 ; ebp
dd 0 ; esi
dd 0 ; edi
dw 0 ; es
dw 0 ; cs
dw 0 ; ss
dw 0 ; ds
dw 0 ; fs
dw 0 ; gs
dw 0 ; ldt
dw 0 ; trace/trap
dw 0 ; i/o bitmap address
[global _tss1_begin]
_tss1_begin:
dw 0 ; back link
dd 0 ; esp0
dw 0 ; ss0
dd 0 ; esp1
dw 0 ; ss1
dd 0 ; esp2
dw 0 ; ss2
dd 0x9C000 ; cr3
dd _task_1 ; eip
dd 0 ; eflags
dd 0 ; eax
dd 0 ; ecx
dd 0 ; edx
dd 0 ; ebx
dd stack ; esp
dd 0 ; ebp
dd 0 ; esi
dd 0 ; edi
dw 0 ; es
dw LINEAR_CODE_SEL ; cs
dw LINEAR_DATA_SEL ; ss
dw 0 ; ds
dw 0 ; fs
dw 0 ; gs
dw 0 ; ldt
dw 0 ; trace/trap
dw 0 ; i/o bitmap address
[global _tss2_begin]
_tss2_begin:
dw 0 ; back link
dd 0 ; esp0
dw 0 ; ss0
dd 0 ; esp1
dw 0 ; ss1
dd 0 ; esp2
dw 0 ; ss2
dd 0x9C000 ; cr3
dd _task_2 ; eip
dd 0 ; eflags
dd 0 ; eax
dd 0 ; ecx
dd 0 ; edx
dd 0 ; ebx
dd stack ; esp
dd 0 ; ebp
dd 0 ; esi
dd 0 ; edi
dw 0 ; es
dw LINEAR_CODE_SEL ; cs
dw LINEAR_DATA_SEL ; ss
dw 0 ; ds
dw 0 ; fs
dw 0 ; gs
dw 0 ; ldt
dw 0 ; trace/trap
dw 0 ; i/o bitmap address
tss2_end:
TSS_SIZE equ (tss2_end - _tss2_begin)
gdt: ;our descriptors
; NULL descriptor
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
; unused descriptor
dw 0
dw 0
db 0
db 0
db 0
db 0
LINEAR_DATA_SEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 92h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
LINEAR_CODE_SEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 9Ah ; present,ring 0,code,non-conforming,readable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
TSS_ENTRY_0 equ $-gdt
desc _tss0_begin, TSS_SIZE, D_TSS
TSS_ENTRY_1 equ $-gdt
desc _tss1_begin, TSS_SIZE, D_TSS
TSS_ENTRY_2 equ $-gdt
desc _tss2_begin, TSS_SIZE, D_TSS
gdt_end:
gdt_ptr:
dw gdt_end - gdt - 1
dd gdt
[/tt]
For some reason, NASM doesn't seem to understand that in:
desc _tss2_begin, TSS_SIZE, D_TSS
_tss2_begin should be an address, and it gives the error mentioned above.
Thanks in advance,
K.J.
TSS problem
Re:TSS problem
you might need to show your definition of the 'desc' macro (which is presumably derived from john fine's technique).
Re:TSS problem
Oops, sorry, I was gonna do that but forgot:
[tt]
;Each descriptor should have exactly one of next 8 codes to define the type of
;descriptor
D_LDT EQU 200h ;LDT segment
D_TASK EQU 500h ;Task gate
D_TSS EQU 900h ;TSS
D_CALL EQU 0C00h ;386 call gate
D_INT EQU 0E00h ;386 interrupt gate
D_TRAP EQU 0F00h ;386 trap gate
D_DATA EQU 1000h ;Data segment
D_CODE EQU 1800h ;Code segment
;Descriptors may include the following as appropriate:
D_DPL3 EQU 6000h ;DPL3 or mask for DPL
D_DPL2 EQU 4000h
D_DPL1 EQU 2000h
D_PRESENT EQU 8000h ;Present
D_NOT_PRESENT EQU 8000h ;Not Present
;Note, the PRESENT bit is set by default
;Include NOT_PRESENT to turn it off
;Do not specify D_PRESENT
;Segment descriptors (not gates) may include:
D_ACC EQU 100h ;Accessed (Data or Code)
D_WRITE EQU 200h ;Writable (Data segments only)
D_READ EQU 200h ;Readable (Code segments only)
D_BUSY EQU 200h ;Busy (TSS only)
D_EXDOWN EQU 400h ;Expand down (Data segments only)
D_CONFORM EQU 400h ;Conforming (Code segments only)
D_BIG EQU 40h ;Default to 32 bit mode (USE32)
D_BIG_LIM EQU 80h ;Limit is in 4K units
%define w_a_n_p_b ;work_around_nasm_prepend_bug
%macro desc 3
w_a_n_p_b
%if (%3) & (~(%3)>>2) & 0x400 ;Gate
dw %1
dw %2
dw (%3)+D_PRESENT
dw (%1) >> 16
%else ;Not a gate
dw %2
dw %1
db (%1) >> 16
db ((%3)+D_PRESENT) >> 8
db (%3) + ((%2) >> 16)
db (%1) >> 24
%endif
%endmacro
[/tt]
K.J.
[tt]
;Each descriptor should have exactly one of next 8 codes to define the type of
;descriptor
D_LDT EQU 200h ;LDT segment
D_TASK EQU 500h ;Task gate
D_TSS EQU 900h ;TSS
D_CALL EQU 0C00h ;386 call gate
D_INT EQU 0E00h ;386 interrupt gate
D_TRAP EQU 0F00h ;386 trap gate
D_DATA EQU 1000h ;Data segment
D_CODE EQU 1800h ;Code segment
;Descriptors may include the following as appropriate:
D_DPL3 EQU 6000h ;DPL3 or mask for DPL
D_DPL2 EQU 4000h
D_DPL1 EQU 2000h
D_PRESENT EQU 8000h ;Present
D_NOT_PRESENT EQU 8000h ;Not Present
;Note, the PRESENT bit is set by default
;Include NOT_PRESENT to turn it off
;Do not specify D_PRESENT
;Segment descriptors (not gates) may include:
D_ACC EQU 100h ;Accessed (Data or Code)
D_WRITE EQU 200h ;Writable (Data segments only)
D_READ EQU 200h ;Readable (Code segments only)
D_BUSY EQU 200h ;Busy (TSS only)
D_EXDOWN EQU 400h ;Expand down (Data segments only)
D_CONFORM EQU 400h ;Conforming (Code segments only)
D_BIG EQU 40h ;Default to 32 bit mode (USE32)
D_BIG_LIM EQU 80h ;Limit is in 4K units
%define w_a_n_p_b ;work_around_nasm_prepend_bug
%macro desc 3
w_a_n_p_b
%if (%3) & (~(%3)>>2) & 0x400 ;Gate
dw %1
dw %2
dw (%3)+D_PRESENT
dw (%1) >> 16
%else ;Not a gate
dw %2
dw %1
db (%1) >> 16
db ((%3)+D_PRESENT) >> 8
db (%3) + ((%2) >> 16)
db (%1) >> 24
%endif
%endmacro
[/tt]
K.J.
Re:TSS problem
Perhaps this isn't the most helpful observation, but in the original version of this way of building tables (started by john fine and propagated by gareth owen), the values passed to the macro (and shifted) were in fact scalar. You may have to take NASM at its word, that it is unhappy trying to shift offsets.
Re:TSS problem
Check out this: http://my.execpc.com/~geezer/johnfine/pmcom02.zip
and this:
http://my.execpc.com/~geezer/johnfine/tasktes1.zip
Same file for making descriptors is used, and he doens't use scalar values, yet it compiles fine and NASM doesn't choke on it.
K.J.
and this:
http://my.execpc.com/~geezer/johnfine/tasktes1.zip
Same file for making descriptors is used, and he doens't use scalar values, yet it compiles fine and NASM doesn't choke on it.
K.J.
Re:TSS problem
tss0???desc???tss0_begin-fixB, tss_size, D_TSS
tss1???desc???tss1_begin-fixD, tss_size, D_TSS
Unless I haven't woken up yet, none of these are offsets. I'll need more coffee before diving into tasktes1. Slurp, slurp.
Neither are these:
tss0???resb???tss_size
SEGMENT DATA
???alignb 16
gdt??? start_gdt
flat_code desc 0,?????? 0xFFBFF, D_CODE+D_READ+D_BIG+D_BIG_LIM
flat_data desc 0,?????? 0xFFFFF, D_DATA+D_WRITE+D_BIG+D_BIG_LIM
tss_dsc:
tss_sel desc tss0,?????? tss_size-1, D_TSS
The offsets are only used to calculate sizes.
tss1???desc???tss1_begin-fixD, tss_size, D_TSS
Unless I haven't woken up yet, none of these are offsets. I'll need more coffee before diving into tasktes1. Slurp, slurp.
Neither are these:
tss0???resb???tss_size
SEGMENT DATA
???alignb 16
gdt??? start_gdt
flat_code desc 0,?????? 0xFFBFF, D_CODE+D_READ+D_BIG+D_BIG_LIM
flat_data desc 0,?????? 0xFFFFF, D_DATA+D_WRITE+D_BIG+D_BIG_LIM
tss_dsc:
tss_sel desc tss0,?????? tss_size-1, D_TSS
The offsets are only used to calculate sizes.
Re:TSS problem
I just happened to notice how mobius (apparently) dealt with the same problem you're having.
%define ONE_MEG 0x100000
%define LOAD_ADDR ONE_MEG
<snip>
dt:
null_desc desc 0,0,0
loader_code desc 0, 0xFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM
loader_data desc 0, 0xFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM
kernel_code desc LOAD_ADDR, 0xFFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM
kernel_data desc LOAD_ADDR, 0xFFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM
flat_code desc 0, 0xFFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM
flat_data desc 0, 0xFFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM
gdtlength equ $ - gdt - 1
%define ONE_MEG 0x100000
%define LOAD_ADDR ONE_MEG
<snip>
dt:
null_desc desc 0,0,0
loader_code desc 0, 0xFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM
loader_data desc 0, 0xFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM
kernel_code desc LOAD_ADDR, 0xFFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM
kernel_data desc LOAD_ADDR, 0xFFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM
flat_code desc 0, 0xFFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM
flat_data desc 0, 0xFFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM
gdtlength equ $ - gdt - 1