I change source data segment attribute,but PC is down,why?

Started by leetow2003, November 23, 2010, 02:50:48 AM

Previous topic - Next topic

leetow2003

;16 jump
jump macro selector,offsetv
  db 0eah
  dw offsetv
  dw selector
endm

;display a char
echoch macro ascii
  mov ah,2
  mov dl,ascii
  int 21h
endm


descriptor struc
  limitl dw 0
  basel dw 0
  basem db 0
  attributes dw 0
  baseh db 0
descriptor ends

pdesc struc
  limit dw 0
  base dd 0
pdesc ends


atdw = 92h
atce = 98h
atdr = 90h ;data read only
  .386P
;--------------------------------------------------------

dseg segment use16
  gdt label byte
  dummy descriptor <>
  code descriptor <0ffffh,,,atce,>
  code_sel =code-gdt
  datas descriptor <0ffffh,0h,11h,atdw,0> ;If atdw change to atdr,PC will down
  datas_sel =datas-gdt
  datad descriptor <0ffffh,,,atdw,>
  datad_sel =datad-gdt
  gdtlen =$-gdt
;
  vgdtr pdesc <gdtlen-1,>
;
  bufferlen = 256
  buffer db bufferlen dup(0)
dseg ends

;-------------------------------------------------------------

cseg segment use16
  assume cs:cseg, ds:dseg
start:
  mov ax,dseg
  mov ds,ax
;
  mov bx,16
  mul bx
  add ax,offset gdt
  adc dx,0
  mov word ptr vgdtr.base,ax
  mov word ptr vgdtr.base+2,dx
;
  mov ax,cs
  mul bx
  mov code.basel,ax
  mov code.basem,dl
  mov code.baseh,dh
;
  mov ax,ds
  mul bx
  add ax,offset buffer
  adc dx,0
  mov datad.basel,ax
  mov datad.basem,dl
  mov datad.baseh,dh
;
  lgdt fword ptr vgdtr
;
  cli
  call ea20
;
  mov eax,cr0
  or eax,1
  mov cr0,eax
;
  jump <code_sel>,<offset virtual>
;
virtual:
  mov ax,datas_sel
  mov ds,ax
  mov ax,datad_sel
  mov es,ax
  cld
  xor si,si
  xor di,di
  mov cx,bufferlen/4
  repz movsd
;
  mov eax,cr0
  and eax,0fffffffeh
  mov cr0,eax
;
  jump <seg real>,<offset real>
;
real:
  call da20
  sti
;
  mov ax,dseg
  mov ds,ax
  mov si,offset buffer
  cld
  mov bp,bufferlen/16
nextline:
  mov cx,16
nextch:
  lodsb
  push ax
  shr al,4
  call toascii
  echoch al
  pop ax
  call toascii
  echoch al
  echoch ' '
  loop nextch
  echoch 0dh
  echoch 0ah
  dec bp
  jnz nextline
;
  mov ax,4c00h
  int 21h
;
toascii proc
  and al,0fh
  add al,'0'
  cmp al,'9'
  seta dl
  movzx dx,dl
  imul dx,7
  add al,dl
  ret   
toascii endp
;
;Open A20
ea20 proc
  push ax
  in al,92h
  or al,2
  out 92h,al
  pop ax
  ret
ea20 endp
;
;Close A20
da20 proc
  push ax
  in al,92h
  and al,0fdh ;0fdh=not 20h
  out 92h,al
  pop ax
  ret
da20 endp
;
cseg ends
  end start

This program will transfer data to another at 110000h in P-mode,and then display
in real mode,I find the source data don't be written,so I change the
segment attribute value:
datas descriptor <0ffffh,0h,11h,atdw,0> =>datas descriptor <0ffffh,0h,11h,atdr,0>
but the PC is down under pure DOS,why?

hutch--

leetow2003,

I have move this here because the code is 16 bit real mode code, it has nothing to do with protected mode programming under Windows.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

japheth

Quote from: leetow2003 on November 23, 2010, 02:50:48 AM
datas descriptor <0ffffh,0h,11h,atdw,0> =>datas descriptor <0ffffh,0h,11h,atdr,0>
but the PC is down under pure DOS,why?

I guess the movsd in protected-mode itself has no problems with a read-only selector in DS. However, you'll have to restore DS to a R/W, 64 kB data selector BEFORE switching back to real-mode, because the attributes of DS can only be changed in protected-mode.

So, actually, your program crashes in real-mode because your program or DOS can't write to the DS segment anymore.

leetow2003

Quote from: japheth on November 23, 2010, 09:50:23 AM
Quote from: leetow2003 on November 23, 2010, 02:50:48 AM
datas descriptor <0ffffh,0h,11h,atdw,0> =>datas descriptor <0ffffh,0h,11h,atdr,0>
but the PC is down under pure DOS,why?

I guess the movsd in protected-mode itself has no problems with a read-only selector in DS. However, you'll have to restore DS to a R/W, 64 kB data selector BEFORE switching back to real-mode, because the attributes of DS can only be changed in protected-mode.

So, actually, your program crashes in real-mode because your program or DOS can't write to the DS segment anymore.

Could you describe it  in detail? I am a little clear.Thank you

japheth

Quote from: leetow2003 on November 23, 2010, 12:20:01 PM
Could you describe it  in detail? I am a little clear.Thank you

But my explanation already was very detailed.

You'll have to set DS to a 64 kB R/W descriptor BEFORE switching back to real-mode!

for example:

  mov ax,datas_sel
  mov ds,ax
  mov ax,datad_sel
  mov es,ax
  cld
  xor si,si
  xor di,di
  mov cx,bufferlen/4
  repz movsd
;
  mov ax,datad_sel            ;<<<<<<<<<<<<<<<<<
  mov ds,ax                   ;<<<<<<<<<<<<<<<<<
  mov eax,cr0
  and eax,0fffffffeh
  mov cr0,eax