昨天赶时间去睡觉来,所以现在才把实验2,3一起写个总结。记得华姐说过,做报告就是对你实验的一个总结。那我写blog也是为了总结和以后回头看看自己走过的路。
好了,废话不多说了,继续。
实验2,3合起来有几个问题暂时还未能解决。
Q:;有三个问题,第一个是TestRead和TestWrite ,DispAL,DispReturn要放在段[SECTION .s32]里面
; 第二个问题是:显示还不能正确显示转换后的字符,为什么?
;对于NORMAL的真正作用暂时还没弄明白
还有TEST的正确用法。
TEST的用法:
格式:TEST OPRD1, OPRD2
这条指令和指令AND类似,也是把两个操作数进行按位“与”操作,但结果不送到操作数OPRD1里面,仅仅影响标志位。该指令执行以后,标志位ZF,PF,SF反映运算结果,标志CF和OF清0
该指令通常用于检测某些位是否为1,但又不希望改变原操作数值的场合。
附代码:(里面有自己写的过程时候的想法或者是一些犯的错误)
;有三个问题,第一个是TestRead和TestWrite ,DispAL,DispReturn要放在段[SECTION .s32]里面
; 第二个问题是:显示还不能正确显示转换后的字符,为什么?
;对于NORMAL的真正作用暂时还没弄明白;
%include "pm.inc"
org 0100h
jmp LABEL_BEGIN
[SECTION .gdt]
;GDT
LABEL_GDT: Descriptor 0, 0, 0
LABEL_DESC_CODE32:Descriptor 0, SegCode32Len - 1, DA_C +DA_32
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW
LABEL_DESC_DATA: Descriptor 0, DataLen -1,DA_DRW
LABEL_DESC_TEST: Descriptor 0500000h, 0ffffh,DA_DRW
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA + DA_32
LABEL_DESC_NORMAL:Descriptor 0, 0ffffh, DA_DRW
LABEL_DESC_CODE16:Descriptor 0, Code16Len - 1,DA_C
LABEL_DESC_LDT: Descriptor 0, LDTLen - 1, DA_LDT ;LDT
;GDT END
GdtLen equ $ -LABEL_GDT
GdtPtr dw GdtLen - 1
dd 0
;GDT选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelcetorTest equ LABEL_DESC_TEST - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorLDT equ LABEL_DESC_LDT - LABEL_GDT
;END OF [SECTION .gdt]
[SECTION .data1]
LABEL_DATA:
SPValueInRealMode dw 0
PMMessage: db "In protect mode now ^_^",0
OffsetPMMessage equ PMMessage -$$
StrTest: db "ABCDEFGHIJKLMNOPQRSTUVWSYZ",0
OffsetStrTest equ StrTest - $$
DataLen equ $ - LABEL_DATA
;END OF [SECTION .DATA1]
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:
times 512 db 0
TopOfStack equ $ - LABEL_STACK - 1
[SECTION .s16];漏掉了.后面的s
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
mov [SPValueInRealMode], sp
mov [LABEL_GO_BACK_TO_REAL+3], ax
;初始化32位代码段描述符
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32 ;加偏移加错了
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32+4], al
mov byte [LABEL_DESC_CODE32+7], ah
;初始化数据段描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA + 2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA+4], al
mov byte [LABEL_DESC_DATA+7], ah
;Iinit code 16
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE16
mov word [LABEL_DESC_CODE16 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE16 + 4], al
mov byte [LABEL_DESC_CODE16 + 7], ah
;Iinit STACK
xor eax, eax
mov ax, ss
shl eax, 4
add eax, LABEL_STACK
mov word [LABEL_DESC_STACK + 2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK + 4], al
mov byte [LABEL_DESC_STACK + 7], ah
;Init LDT IN GDT
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT
mov word [LABEL_DESC_LDT + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT + 4], al
mov byte [LABEL_DESC_LDT + 7], ah
;IInit LDT 's Descriptor 对于LDT里面的描述符为什么放在 .s16这个部分里面呢?
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_A
mov word [LABEL_LDT_DESC_CODE_A + 2], ax
shr eax, 16
mov byte [LABEL_LDT_DESC_CODE_A + 4], al
mov byte [LABEL_LDT_DESC_CODE_A + 7], ah
;加载gdtr做准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT
mov dword [GdtPtr+2], eax ;忘记+2
lgdt [GdtPtr]
cli
in al, 92h
or al,00000010b
out 92h, al
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword SelectorCode32:0
[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorData
mov ds, ax
mov ax, SelcetorTest
mov es, ax
mov ax, SelectorVideo
mov gs, ax
mov ax, SelectorStack
mov ss, ax
mov esp, TopOfStack
;显示字符
; push edi
; push esi
xor edi, edi
mov edi, (80*10+10)*2
xor esi, esi
mov esi, OffsetPMMessage
mov ah, 0ch
cld
.1:
lodsb
test al, al ;只能跟al进行对比,需要查一下test的用法
jz .2
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
; pop esi
; pop edi
call DispReturn
; call TestRead
; call TestWrite
; call TestRead
; call DispReturn
;Load LDT
mov ax, SelectorLDT
lldt ax
jmp SelectorLDTCodeA:0
TestRead:
xor esi, esi
mov ecx, 8
.loop: ;忘记写冒号
mov al, [es:esi]
call DispAL
inc esi
loop .loop
call DispReturn
ret
;TestRead结束
TestWrite:
push esi
push edi
xor esi, esi
xor edi, edi
mov esi, OffsetStrTest
cld
.1:
lodsb
test al, al ;不能test al,0 为什么呢?
jz .2
mov [es:edi], al
inc edi
jmp .1
.2:
pop edi
pop esi
ret
;TestWrite结束
DispAL:
push ecx
push edx
mov ah, 0CH
mov dl, al
shr al, 4
mov ecx, 2
.begin:
and al, 01111b
cmp al, 9
ja .1
add al, '0'
jmp .2
.1:
sub al, 0Ah
add al, 'A'
.2:
mov [gs:edi], ax
add edi, 2
mov al, dl
loop .begin
add edi, 2
pop edx
pop ecx
ret
;****DispAL END
DispReturn:
push eax;
push ebx
mov eax, edi
mov bl, 160
div bl
and eax, 0ffh
inc eax
mov bl,160
mul bl
mov edi, eax
pop ebx
pop eax
ret
;*******DispReturn END
SegCode32Len equ $ - LABEL_SEG_CODE32 ;上面的子程序不能放到其他位置,为什么呢?
;END OF[SECTION .S32]
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:
mov ax, SelectorNormal
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and al, 11111110b
mov cr0, eax
LABEL_GO_BACK_TO_REAL:
jmp 0:LABEL_REAL_ENTRY
Code16Len equ $ - LABEL_SEG_CODE16
[SECTION .real]
[BITS 16]
LABEL_REAL_ENTRY:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, [SPValueInRealMode]
in al, 92h
and al, 11111101b
out 92h, al
sti
mov ax, 4c00h
int 21h
;REAL END
;***************
;LDT
[SECTION .ldt]
ALIGN 32
LABEL_LDT:
LABEL_LDT_DESC_CODE_A: Descriptor 0, CodeALen - 1, DA_C + DA_32
LDTLen equ $ - LABEL_LDT
;LDT Selector
SelectorLDTCodeA equ LABEL_LDT_DESC_CODE_A - LABEL_LDT + SA_TIL
;END OF SECTION .ldt
;CODEA
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax
mov edi, (80*2 + 0) * 2
mov ah, 0ch
mov al, 'L'
mov [gs:edi], ax
jmp SelectorCode16:0
CodeALen equ $ - LABEL_CODE_A
;END OF SECTION .LA