News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

NOOB question

Started by MASM, January 02, 2012, 03:05:57 PM

Previous topic - Next topic

MASM

my MASM version is 6.0 AND I think I left my manual at home when I moved out.

I am messing around with a piece of code which puts the 80386 into protected mode.

After switching to protected mode I want to do the same thing as before, outputting a character on the display

oops - now I see, it should read B8000 rather than 68000.

so you are saying my segment must not exceed 64kB in protected mode????


dedndave

the segment register is only 16 bits, so it can hold a max value of 0FFFFh
the offset - same thing
so, to obtain a 20-bit address....

look carefully at this little math ditty...
XXXX.    segment (16-bit hex)
.XXXX    offset (16-bit hex)
-----    +
XXXXX    address (20-bit hex)


dedndave

i think that manual is for version 6.14, which is signifigantly different from version 6.10
you can obtain version 6.14 here
ftp://ftp.microsoft.com/softlib/mslfiles/ML614.EXE
or download and install the MASM32 package


MASM

thanks for the link!

that's what I have been looking for

I downloaded version 6.1 which is closest to 6.0

..

MASM

about the math

I know the math for real mode.

now actually I thought the MOV ES:[..] would work with an 32 bit offset rather than a 16 bit offset in protected mode.

now that I have a prog guide I can look these things up

dedndave

in 32-bit code, we rarely use the segment registers (which are then called "selectors", as they look up info in a table)
you can directly address 4 Gb of space with a single 32 bit register   :P

MASM

Please forgive me one last question:

(I looked it up in the MASM manual but what I came up with in the end looked to me like some pointer)

how do I say in 32 mode MOVE 41H into memory location B8000H ?

assuming a FLAT memory model with the segment base address tied to 0H

dedndave

ok - the flat memory model is for 32-bit code
in which case, you can directly address up to 4 gb with a register
however, in 32-bit you are in protected mode - you cannot access the video buffer directly

for 16-bit code (real mode), you load a segment register (probably DS or ES) with B800h
the segment register value is multiplied by 16 to provide the segment base address
then, you can access up to 64 kb of the video buffer with a register, starting at 0

the video buffer is only 32 kb in size   :P

MASM

why shouldn't I be able to access the video ram in protected mode?

I got a piece of code which switches my system to protected mode

my program runs on privilege level 0

I come out in text mode (NO WINDOWS)




MASM

maybe something like this would work ? MOV [B8000H],41H

redskull

Since you have switched into protected mode yourself, what selectors in the GDT/LDT did you make?  If you don't know (or just copy and pasted what someone else did), you have lots of studying of the Intel manuals ahead of you.  Like dave said, access is through selectors, so it the end result depends on how you configured the GDT/LDT.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

MichaelW

Quote from: dedndave on January 08, 2012, 03:30:22 PM
the video buffer is only 32 kb in size   :P

It is 32KB for the alphanumeric modes, but 64KB for the graphics modes (segment address A000h).
eschew obfuscation

MichaelW

Quote from: MASM on January 08, 2012, 09:12:50 PM
why shouldn't I be able to access the video ram in protected mode?

You can. At one time I had a memory test application that ran in PM and that displayed by directly manipulating the display buffer (and the VGA hardware via I/O ports for cursor control). To do this I included a descriptor for the display (alphanumeric) buffer in my GDT, and at runtime loaded the selector for it into ES. The essential parts of the code are below. Note that you should probably ignore the IDT stuff and just keep interrupts disabled, and that I set everything up so the application actually executed in the graphics display buffer so it could test the memory as one contiguous chunk, instead of having to dance around the application code, data, and stack. So the BASE...MUST BE ADJUSTED comments are included because the application code, data, and stack get moved at runtime.

; Structure for segment descriptors
; Access rights byte:
;       P:1             Present (in memory)
;       DPL:2           Descriptor privilege level (0-3)
;       S:1             Segment descriptor (code/data/stack)
;       E:1             Executable (code)
;       C/ED:1          Conforming (code)/Expand down (stack)
;       R/W:1           Readable/Writeable (code/data)
; Extra byte:
;       G:1             Granularity (page)
;       D:1             Default operand size (32 bits)
;       Z:1             Must be 0
;       AVL:1           Available
;       limit_high:4    Segment limit 19-16
SEGMENT_DESCRIPTOR struc
seg_limit_low           dw      0
seg_base_low            dw      0
seg_base_mid            db      0
seg_access_rights       db      0
seg_extra_byte          db      0
seg_base_high           db      0
SEGMENT_DESCRIPTOR ends

; Structure for gate descriptors
; Extra byte:
;       Z:3             Must be 0
;       WORD_COUNT:5    Call gates only
; Access rights byte:
;       P:1             Present (in memory)
;       DPL:2           Descriptor privilege level (0-3)
;       Z:1             Must be 0
;       TYPE:4          Should be 06h for 286 interrupt gate
GATE_DESCRIPTOR struc
gate_offset_low         dw      0
gate_selector           dw      0
gate_extra_byte         db      0
gate_access_rights      db      0
gate_offset_high        dw      0
GATE_DESCRIPTOR ends

; Structure for table descriptors
TABLE_DESCRIPTOR struc
table_limit             dw      0
table_base              dd      0
TABLE_DESCRIPTOR ends

CODE_SELECTOR   equ     8       ; Code segment
DATA_SELECTOR   equ     16      ; Data/stack segment
VIDEO_SELECTOR  equ     24      ; Video buffer segment (for display from PM)
TEST_SELECTOR   equ     32      ; Test segment (entire address space)

R_MULT          equ     16      ; Refresh period multiplier

.model small,c
.stack                          ; Defaults to 1024 bytes

.data

; Create and initialize IDT
;       Offset low w:   Offset of handler
;       Selector w:     CODE_SELECTOR
;       Extra b:        0 (default)
;       AR b:           P = 1, DPL = 00, 0, TYPE = 0006h
;       Offset high w:  0 (default)
; Note that the code segment descriptor is recognized as a
; 286 descriptor because the most significant word is 0
; NMI is Int 02, others for debugging
idt GATE_DESCRIPTOR     <offset Isr00, CODE_SELECTOR, , 86h>, \
<offset Isr01, CODE_SELECTOR, , 86h>, \
<offset Isr02, CODE_SELECTOR, , 86h>, \
<offset Isr03, CODE_SELECTOR, , 86h>, \
<offset Isr04, CODE_SELECTOR, , 86h>, \
<offset Isr05, CODE_SELECTOR, , 86h>, \
<offset Isr06, CODE_SELECTOR, , 86h>, \
<offset Isr07, CODE_SELECTOR, , 86h>
    GATE_DESCRIPTOR     <offset Isr08, CODE_SELECTOR, , 86h>, \
<offset Isr09, CODE_SELECTOR, , 86h>, \
<offset Isr0A, CODE_SELECTOR, , 86h>, \
<offset Isr0B, CODE_SELECTOR, , 86h>, \
<offset Isr0C, CODE_SELECTOR, , 86h>, \
<offset Isr0D, CODE_SELECTOR, , 86h>, \
<offset Isr0E, CODE_SELECTOR, , 86h>, \
<offset Isr0F, CODE_SELECTOR, , 86h>
    GATE_DESCRIPTOR     <offset Isr10, CODE_SELECTOR, , 86h>, \
<offset Isr11, CODE_SELECTOR, , 86h>, \
<offset Isr12, CODE_SELECTOR, , 86h>, \
<offset Isr13, CODE_SELECTOR, , 86h>, \
<offset Isr14, CODE_SELECTOR, , 86h>, \
<offset Isr15, CODE_SELECTOR, , 86h>, \
<offset Isr16, CODE_SELECTOR, , 86h>, \
<offset Isr17, CODE_SELECTOR, , 86h>
    GATE_DESCRIPTOR     <offset Isr18, CODE_SELECTOR, , 86h>, \
<offset Isr19, CODE_SELECTOR, , 86h>, \
<offset Isr1A, CODE_SELECTOR, , 86h>, \
<offset Isr1B, CODE_SELECTOR, , 86h>, \
<offset Isr1C, CODE_SELECTOR, , 86h>, \
<offset Isr1D, CODE_SELECTOR, , 86h>, \
<offset Isr1E, CODE_SELECTOR, , 86h>, \
<offset Isr1F, CODE_SELECTOR, , 86h>

; Create and initialize GDT
; BASE FOR DATA SEGMENT MUST BE ADJUSTED AT RUN TIME
; Null selector first
; Code segment initialized for operation from VGA display buffer
;       Limit low w:    0ffffh
;       Base low w:     9000h
;       Base mid b:     0bh
;       AR b:           P = 1, DPL = 00, S = 1, E = 1, C = 0, R = 1, A = 0
;       Extra b:        G = 0, 0, AVL = 0, D = 0, limit_high = 0000 (default)
; Data/stack segment initialized for operation from VGA display buffer
;       Limit low w:    0ffffh
;       Base low w:     9000h
;       Base mid b:     0bh
;       AR b:           P = 1, DPL = 00, S = 1, E = 0, ED = 0, W = 1, A = 0
;       Extra b:        G = 0, 0, AVL = 0, D = 0, limit_high = 0000 (default)
; Video buffer segment initialized for buffer access from PM
;       Limit low w:    0ffffh
;       Base low w:     8000h
;       Base mid b:     0bh
;       AR b:           P = 1, DPL = 00, S = 1, E = 0, ED = 0, W = 1, A = 0
;       Extra b:        G = 0, 0, AVL = 0, D = 0, limit_high = 0000 (default)
; Test segment initialized for maximum segment limit and page granularity
;       Limit low w:    0ffffh
;       Base low w:     0 (default)
;       Base mid b:     0 (default)
;       AR b:           P = 1, DPL = 00, S = 1, E = 0, ED = 0, W = 1, A = 0
;       Extra b:        G = 1, 0, AVL = 0, D = 0, limit_high = 0fh
gdt SEGMENT_DESCRIPTOR  <>, \
< 0ffffh, 9000h, 0bh, 9ah >, \
< 0ffffh, 9000h, 0bh, 92h >, \
< 0ffffh, 8000h, 0bh, 92h >, \
< 0ffffh, , , 92h, 8fh >

; Create IDT descriptor and initialize base and limit
; BASE MUST BE ADJUSTED AT RUN TIME
idt_descriptor TABLE_DESCRIPTOR  <32 * 8 - 1, 0b9000h>

; Create GDT descriptor and initialize base and limit
; BASE MUST BE ADJUSTED AT RUN TIME
gdt_descriptor TABLE_DESCRIPTOR  <5 * 8 - 1, 0b9000h>

. . .

; Load descriptor table registers
lidt    fword ptr [idt_descriptor]
lgdt    fword ptr [gdt_descriptor]

; Initialize far pointer for mode change
mov     word ptr jmp_ptr,offset reentry
mov     word ptr jmp_ptr[2],CODE_SELECTOR

; Go to PM
mov     eax,cr0
or      al,01h
mov     cr0,eax

; Do intersegment jump to set cs and flush instruction queue
jmp     dword ptr jmp_ptr
reentry:

; Load descriptor caches
push    DATA_SELECTOR
pop     ds
push    DATA_SELECTOR
pop     ss
push    VIDEO_SELECTOR
pop     es

eschew obfuscation