顯示具有 x86 標籤的文章。 顯示所有文章
顯示具有 x86 標籤的文章。 顯示所有文章

2016年1月8日 星期五

進出 x86 保護模式 - 使用 masm

這是 80x86 汇编语言程序设计教程的範例程式,書中的版本有點錯誤, 我做了一點修正。

我自然不熟悉 masm, 通常我的開發環境都是 linux。會使用 masm 來測試這個程式, 純粹是好玩。我已經有了 gas, nasm 的進入保護模式的版本, 想再補上 masm。

如何使用 masm 5.0 讓我傷透腦筋, masm 5.0 可以在 windows xp 執行, 卻不能在 windows 8 執行, 我得在 windows xp 使用 masm, 並把執行檔想辦法傳到 linux/qemu 上, 繞了一大圈總算搞定。

組譯完成後的是一個 dos exe 檔案, 我在 qemu/dos 上測試, 沒問題, 保險起見, 又在真實機器上以 dos 為開機片再測試過, 真的可以正確執行。

spm.asm
  1 ; test by masm 5.0
  2 ; t10-1.asm 80x86 汇编语言程序设计教程 page 376
  3 JUMP MACRO selector, offsetv
  4   DB 0eah
  5   DW offsetv
  6   DW selector
  7   ENDM
  8 
  9 ECHOCH MACRO ascii
 10   mov ah, 2
 11   mov dl, ascii
 12   int 21h
 13   endm
 14 
 15 DESCRIPTOR STRUC
 16 LIMITL DW 0
 17 BASEL DW 0
 18 BASEM DB 0
 19 ATTRIBUTES DW 0
 20 BASEH DB 0
 21 DESCRIPTOR ENDS
 22 
 23 PDESC STRUC
 24 LIMIT DW 0
 25 BASE DD 0
 26 PDESC ENDS
 27 
 28 ATDW = 92H
 29 ATCE = 98H
 30 .386P
 31 
 32 DSEG SEGMENT USE16
 33 GDT LABEL BYTE
 34 DUMMY DESCRIPTOR <>
 35 CODE DESCRIPTOR <0FFFFH,,,ATCE,>
 36 CODE_SEL = CODE - GDT
 37 DATAS DESCRIPTOR <0FFFFH,0H,11H,ATDW,0>
 38 DATAS_SEL = DATAS - GDT
 39 DATAD DESCRIPTOR<0FFFFH,,,ATDW,>
 40 DATAD_SEL = DATAD - GDT
 41 GDTLEN = $ - GDT
 42 VGDTR PDESC <GDTLEN-1>
 43 BUFFERLEN = 256
 44 BUFFER DB BUFFERLEN DUP(0)
 45 DSEG ENDS
 46 
 47 CSEG SEGMENT USE16
 48   ASSUME CS:CSEG, DS:DSEG
 49 START:
 50   xchg bx, bx
 51   mov ax, dseg
 52   mov ds, ax
 53   mov bx, 16
 54   mul bx
 55   add ax, offset gdt
 56   adc dx, 0
 57   mov word ptr vgdtr.base, ax
 58   mov word ptr vgdtr.base+2, dx
 59   mov ax, cs
 60   mul bx
 61   mov code.basel, ax
 62   mov code.basem, dl
 63   mov code.baseh, dh
 64   mov ax, ds
 65   mul bx
 66   add ax, offset buffer
 67   adc dx, 0
 68   mov datad.basel, ax
 69   mov datad.basem, dl
 70   mov datad.baseh, dh
 71 
 72   lgdt qword ptr vgdtr
 73 
 74   cli
 75   call ea20
 76 
 77   mov eax, cr0
 78   or eax, 1
 79   mov cr0, eax
 80 
 81   JUMP <CODE_SEL>, <OFFSET VIRTUAL>
 82 
 83 VIRTUAL:
 84   mov ax, datas_sel
 85   mov ds, ax
 86   mov ax, datad_sel
 87   mov es, ax
 88   cld
 89   xor si, si
 90   xor di, di
 91   mov cx, bufferlen/4
 92   repz movsd
 93 
 94   mov eax, cr0
 95   and eax, 0fffffffeh
 96   mov cr0, eax
 97 
 98   JUMP <SEG REAL>,<OFFSET REAL>
 99 
100 REAL:
101   call da20
102   sti
103   mov ax, dseg
104   mov ds, ax
105   mov si, offset buffer
106   cld
107   mov bp, bufferlen/16
108 NEXTLINE:
109   mov cx, 16
110 NEXTCH:
111   lodsb
112   push ax
113   shr al, 4
114   call toascii
115   ECHOCH al
116   pop ax
117   call toascii
118   echoch al
119   echoch ' '
120   loop nextch
121   echoch 0dh
122   echoch 0ah
123   dec bp
124   jnz nextline
125 
126   mov ax, 4c00h
127   int 21h
128 
129 TOASCII PROC
130         and    al, 0fh
131         cmp     al, 9
132         ja      EN
133         add    al, 030h
134         jmp     EX
135 EN:
136         sub     al, 0ah
137         add     al, 041h
138 EX:
139         ret
140 TOASCII ENDP
141 
142 EA20 PROC
143   push ax
144   in al, 92h
145   or al, 2
146   out 92h, al
147   pop ax
148   ret
149 EA20 ENDP
150 
151 DA20 PROC
152   push ax
153   in al, 92h
154   and al, 0fdh
155   out 92h, al
156   pop ax
157   ret
158 DA20 ENDP
159 
160 
161 
162 
163 
164 CSEG ENDS
165   END START
166