big real mode ...always reboot...!!why?

Started by guesehsaio, March 30, 2005, 05:09:00 PM

Previous topic - Next topic

guesehsaio

i download this program @ internet...
;
; bigreal.asm
;
; Programmer: David Lindauer
; Date: August 16,1995
; email address: gclind01@ulkyvx.louisville.edu
;
;
; Enable big real mode on FS,GS
;
;

    .MODEL SMALL
    .386P

MEMSIZE = 400000h   ; Set this to MB you want to test
MEMBASE = 100000h

;---------------------------------------------------------------------
; Various symbols used to make things more readable.
;
;---------------------------------------------------------------------

NUMGDT  = 2     ; Number of entries in GDT.

GDTSIZE = NUMGDT*8

;
; Selectors, RPL = 0, in GDT
;
DS386   EQU 8h     ; 386 data segment selector

;---------------------------------------------------------------------
; Define ordering of segments.
;
;---------------------------------------------------------------------
DGROUP  GROUP   seg8086

SEG8086 SEGMENT dword USE16 public 'CODE'
SEG8086 ends

;---------------------------------------------------------------------
; Define a 1K entry stack.
;
;---------------------------------------------------------------------

    .STACK 256


;---------------------------------------------------------------------
; IDT and GDT are first so they will be DWORD aligned
;
;---------------------------------------------------------------------
SEG8086 SEGMENT
;
; The constructed GDT
;
tgdt   dw   0,0,0,0
   db   0ffh,0ffh,0,0,0,92h,0cfh,0
;
; The value to load with the lgdt reg
;
pGDT    dw  GDTSIZE-1   ; Protected mode GDT register
gdtadr  dd  offset tGDT ; Move this out of ROM!!!!!
;
msg   db   "Failure attempting to init a20 line",10,13,'$'
goodmsg db   "Test ok",10,13,'$'
badmsg   db   "Test failed",10,13,'$'
SEG8086 ends

seg8086 SEGMENT
    assume cs:dgroup
bigreal proc
    cld
    cli                         ; Interrupts clear throughout

    sub ebx,ebx
    mov bx,cs                   ; Set ES=DS=CS=DGROUP
    mov ds,bx
    mov es,bx

    ;
    ; Fixup the GDT with our current location in memory.
    ;
    shl ebx,4
    add [gdtadr],ebx      ; GDT and IDT regs must have a physical value

    ; Load the GDT descriptor
    lgdt    [fword ptr pGDT]

    ;
    ; Switch to protected mode.
    ;
    mov ebx,CR0     ; Set protected mode
    inc bx
    mov CR0,ebx
    ;
    ; Load fs & gs with big segs
    ;
    push DS386
    pop fs
    push DS386
    pop gs
    ;
    ; Switch back to real mode
    ;
    dec bx
    mov CR0,ebx
    ret
bigreal endp
;
; Routine to wait till KB controller not busy
;
kb_busy proc
    xor cx,cx      ; Loop 65536 times
kb_bs2:
    in al,64h      ; Get status
    jmp $+2
    jmp $+2
    test al,2      ; See if busy
    jz kb_busy_done     ; Not busy any more
    loop kb_bs2
    stc
    ret
kb_busy_done:
    clc
    ret
kb_busy endp
;
; Routine to wait till KB data buffer empty
;
kb_writewait proc
    xor cx,cx       ; Loop 65536 times
kb_rd2:
    in al,64h      ; Get port status
    test al,2      ;
    jz short kb_writewait_done   ; Quit if buffer empty
    loop kb_rd2      ; Wait a while
    stc         ; Error
    ret
kb_writewait_done:
    clc
    ret
kb_writewait endp
;
; Routine to wait till KB data buffer fll
;
kb_readwait proc
    xor cx,cx       ; Loop 65536 times
kb_rdrd2:
    in al,64h      ; Get port status
    test al,1      ;
    jnz short kb_readwait_done   ; Quit if buffer empty
    loop kb_rdrd2      ; Wait a while
    stc         ; Error
    ret
kb_readwait_done:
    mov cx,32      ; Wait for controller to set data
delay:
    jmp $+2
    jmp $+2
    loop delay      ;
    clc
    ret
kb_readwait endp
;
; Routine to turn on A20 line
;
seta20   proc
    cli         ; Don't want a keypress now!
    call kb_busy   ; Wait while busy
    jc short error      ;
    mov al,0d0h      ; Command to get port status
    out 64h,al      ;
    call kb_busy   ; Wait while busy
    jc short error   
    call kb_readwait   ; Wait for it to put the char there
    jc short error
    in al,60h      ; Get the data
    or al,2      ; Set the A20 bit
    xchg al,ah      ; Data to ah
    call kb_busy   ; Wait while busy
    jc short error
    mov al,0d1h      ; Command to put port status
    out 64h,al      ;
    call kb_busy   ; Wait while busy
    jc short error
    call kb_writewait   ; Wait for buffer to empty
    jc short error
    mov al,ah      ; Write the data
    out 60h,al      ;
    clc         ; No erros
error:
    sti         ; Keys allowed now
    ret
seta20   endp
;
; Fill extended memory with a pattern
;
fillmegs proc
    mov edi,MEMBASE
    mov ecx,MEMSIZE / 4
    mov eax,0ffff0000h
fmlp:
    mov fs:[edi],eax
    add edi,4
    inc eax
    loop fmlp
;    mov dword ptr fs:[edi-16],0  ; put this line in to observe a failure
    ret
fillmegs endp
;
; See if pattern overwrote itself
;
testmegs proc
    mov edi,MEMBASE
    mov ecx,MEMSIZE/4
    mov eax,0ffff0000h
cmlp:
    cmp fs:[edi],eax
    jnz short badcmp
    add edi,4
    inc eax
    loop cmlp
    mov dx,offset goodmsg
    jmp short pmsg
badcmp:
    mov dx,offset badmsg
pmsg:
    mov ah,9
    int 21h
    ret
testmegs endp
       
    ;
start:
    call seta20
    jc short bada20
    call bigreal   ; Switch FS & GS to large seg sizes
    call fillmegs
    call testmegs

done:
    mov ah,04ch      ; Back to DOS; big limits on everything.
    int 21h
bada20:
    mov dx,offset msg
    mov ah,9
    int 21h
    jmp done
SEG8086 ends

    end start
;***********
masm 6.11;why i always restart??please tell me ,tks......
i try to trace this program ,use debug32 it's trace to "mov cr0,ebx" then reboot......

MichaelW

I think the problem has something to do with the condition of the system when you execute the program. When I tried to execute it from Windows 98 MS-DOS Mode, it hung. When I tried to execute it from a Windows 98 boot disk, it also hung. In both cases, the processor was in real mode, but himem.sys had been loaded, so it had already taken over control of the A20 address line. When I created a bare Windows 98 boot disk (without a config.sys or autoexec.bat), booted from the disk, and executed the program, it returned "Test ok".

Thinking about this more, I realized that in addition to himem.sys being loaded, some OS components had been moved into the high memory area (HMA). From config.sys for the Windows 98 boot disk:

device=himem.sys /testmem:off
...
dos=high,umb

And because MEMBASE is set to the start of the HMA, the test is overwriting everything there, and the problem occurs at some point after the return to DOS.
eschew obfuscation

guesehsaio

thank you for your detail explain !!and i have another question..................
for example: i write membase:100000h (1MB)~c800000(200MB) ...if it retuend "test ok" and my question....how verify it really write 1MB~200MB??
use debug32??but it just can see ffff:ffff  "value"....can you tell me??in this program ...it's write to fs:edi....can i verify "value" that 1MB~200MB??and how?
thank you .......!!maybe you don't understand my mean.....because my english very poor!!sorry........but i hope you can help me!

MichaelW

I'm not familiar with debug32. The code looks correct to me, so I don't see how it could fail. But if you feel a need to verify, one easy method would be to change the code so the value written to each dword is the address of the dword:
Change:

mov fs:[edi],eax

To:

mov fs:[edi],edi

And:

cmp fs:[edi],eax

To:

mov fs:[edi],edi

Then for some number of addresses spread out through the range, compare the stored value to the address and display a message based on the result. Because DOS does not use FS or GS, the segment limit should stick until the system is rebooted.
eschew obfuscation

thomasantony

Hi,
   Have you tried it from 'Safe mode Command Prompt'? You select that one from the boot menu you get by pressing F8 while windows loads. I think this one doesn't load himem.sys .

Thomas Antony
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

guesehsaio

thank you Michael and Thomas..
i have a lot of question ...i am a beginner of assembly..and ask stupid  question! i have some question :P
1.DS386   EQU 8h     ; 386 data segment selector
    ; Load fs & gs with big segs
    ;
    push DS386
    pop fs
    push DS386
    pop gs
    ;
    i trace this....GS=FS=0008 ,why this is 8? may i change DS386= 0???
2.what different big real mode and protected mode ??
3.mov fs:[edi],eax ..if edi=00100000h ! it's mean 1MB liner address @ memory??
  and if i want written 256MB, this address @ memory...
  mov edi,10000000h
  mov fs:[edi],eax
  fs:10000000h =256MB @ liner address??
thank your answer!!!

MichaelW

The first descriptor in the GTD must be a "null descriptor". Each descriptor is 8 bytes in length, so the second descriptor starts at offset 8.

; The constructed GDT
;
  tgdt  dw  0,0,0,0   ; null decriptor
        db  0ffh,0ffh,0,0,0,92h,0cfh,0


The purpose of the null descriptor is to guarantee that a reference to an unused segment register will generate an exception.


SEGMENT_DESCRIPTOR struc
seg_limit_low     dw  0ffffh
seg_base_low      dw  0
seg_base_mid      db  0
seg_access_rights db  92h
seg_extra_byte    db  0cfh
seg_base_high     db  0
SEGMENT_DESCRIPTOR ends

The definitons of some of the bits will be different for
a system or application code segment.
Access rights byte:
92h = 10010010b
      ||||||||
      |||||||+-- 0 = not accessed
      ||||||+--- 1 = write enable
      |||||+---- 0 = not expand down
      ||||+----- 0 = data segment
      |||+------ 1 = application segment (not system segment)
      |++------- 00 = privilege level 0
      +--------- 1 = segment present in memory
Extra byte:
0cfh = 11001111b
       ||||||||
       ||||++++-- 1111 = limit high (bits 19-16)
       |||+------ 0 = not availabe for use by system
       ||+------- must be zero
       |+-------- 1 = default operand size is 32 bits
       +--------- 1 = page granularity (limit scaled by 4096)


The primary differences between big real mode and protected are the differences between real and protected mode. The primary difference between normal real mode and big real mode is that for big real mode the segment limit has been forced to a larger value that the default 0ffffh.

The linear address is the segment base address plus the offset address. For a segment base of zero, the linear address equals the offset address.
eschew obfuscation

Farabi

HI. I have try the big real mode. With big real mode you will not confuse with the interupt. You can still use interupt.
Some function is cannot be done from protected mode(difficult to code), like set video function and disk access function, thats why I think big real mode is usefull.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

guesehsaio

thank you very much Michael and Farabi...i  try to develop ram test tool (like Ram Stress Test;memtest+86)..but i'm beginner ! so i want to know "Value" @ memory address.i think it's very long that develop software.it will have many question....if i have difficult problem, may i  earnestly request your help??
this forum,and you help me to very much .....and you can understand my english, i'm so surprised!!TKS.

Farabi

Quote from: guesehsaio on April 04, 2005, 05:06:56 PM
thank you very much Michael and Farabi...i  try to develop ram test tool (like Ram Stress Test;memtest+86)..but i'm beginner ! so i want to know "Value" @ memory address.i think it's very long that develop software.it will have many question....if i have difficult problem, may i  earnestly request your help??
this forum,and you help me to very much .....and you can understand my english, i'm so surprised!!TKS.

Hi. If you dont know, asking about protected mode is an advance question. If you want the software development fast, I suggest you to use the function available. www.google.com is agreat aid.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

guesehsaio

 ;
    ; Load fs & gs with big segs
    ;
   push DS386
   pop fs
   push DS386
   pop gs
   push ds386
   pop es
;**************************
MEMSIZE         EQU     08000000h ; Set this to MB you want to test
MEMBASE         EQU     0100000h

fillmegs proc near
    CALL CACHE_OFF
    push ecx
    mov edi,MEMBASE
    mov eax,0AAAAAAAAh
    mov ecx,MEMSIZE /4
loop3:  mov es:[edi],eax
   
    cmp es:[edi],eax
   
    jnz badcmp
    add edi,4
    loop loop3
;******************************
i use "ES"   to displace "FS" !  But i  really filled 1MB~256MB??
i try to use "debug32" trace this program !  discover
0000:00100000~00100FF00 => i filled "value" ,but 0000:00100FF00  above isn't my "value"
0001:00100000~00100FF00=> i filled "Value" ,but 0000:00100FF00 above isn't my "value"
why?? i filled just about "63K Byte"???

MichaelW

In your original post the test code was in a 16-bit segment, and AFAIK in a 16-bit segment the loop instruction uses CX for the loop counter. You could try substituting LOOPD for LOOP to force the use of ECX for the loop counter.

eschew obfuscation

guesehsaio

[ You could try substituting LOOPD for LOOP to force the use of ECX for the loop counter.
thanks....that's ok....!!
loopd  solved my question!thanks.......