博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
p39
阅读量:5055 次
发布时间:2019-06-12

本文共 7317 字,大约阅读时间需要 24 分钟。

; ==========================================; pmtest2.asm; 编译方法:nasm pmtest2.asm -o pmtest2.com; ==========================================%include    "pm.inc"    ; 常量, 宏, 以及一些说明    org    0100h    jmp    LABEL_BEGIN[SECTION .gdt]; GDT;                            段基址,        段界限 , 属性LABEL_GDT:         Descriptor    0,              0, 0         ; 空描述符LABEL_DESC_NORMAL: Descriptor    0,         0ffffh, DA_DRW    ; Normal 描述符LABEL_DESC_CODE32: Descriptor    0, SegCode32Len-1, DA_C+DA_32; 非一致代码段, 32LABEL_DESC_CODE16: Descriptor    0,         0ffffh, DA_C      ; 非一致代码段, 16LABEL_DESC_DATA:   Descriptor    0,      DataLen-1, DA_DRW    ; DataLABEL_DESC_STACK:  Descriptor    0,     TopOfStack, DA_DRWA+DA_32; Stack, 32 位LABEL_DESC_TEST:   Descriptor 0500000h,     0ffffh, DA_DRWLABEL_DESC_VIDEO:  Descriptor  0B8000h,     0ffffh, DA_DRW    ; 显存首地址; GDT 结束GdtLen        equ    $ - LABEL_GDT    ; GDT长度GdtPtr        dw    GdtLen - 1    ; GDT界限        dd    0        ; GDT基地址; GDT 选择子SelectorNormal        equ    LABEL_DESC_NORMAL    - LABEL_GDTSelectorCode32        equ    LABEL_DESC_CODE32    - LABEL_GDTSelectorCode16        equ    LABEL_DESC_CODE16    - LABEL_GDTSelectorData        equ    LABEL_DESC_DATA        - LABEL_GDTSelectorStack        equ    LABEL_DESC_STACK    - LABEL_GDTSelectorTest        equ    LABEL_DESC_TEST        - LABEL_GDTSelectorVideo        equ    LABEL_DESC_VIDEO    - LABEL_GDT; END of [SECTION .gdt][SECTION .data1]     ; 数据段ALIGN    32[BITS    32]LABEL_DATA:SPValueInRealMode    dw    0; 字符串PMMessage:        db    "In Protect Mode now. ^-^", 0    ; 在保护模式中显示OffsetPMMessage        equ    PMMessage - $$StrTest:        db    "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0OffsetStrTest        equ    StrTest - $$DataLen            equ    $ - LABEL_DATA; END of [SECTION .data1]; 全局堆栈段[SECTION .gs]ALIGN    32[BITS    32]LABEL_STACK:    times 512 db 0TopOfStack    equ    $ - LABEL_STACK - 1; END of [SECTION .gs][SECTION .s16][BITS    16]LABEL_BEGIN:    mov    ax, cs    mov    ds, ax    mov    es, ax    mov    ss, ax    mov    sp, 0100h    mov    [LABEL_GO_BACK_TO_REAL+3], ax    mov [LABEL_SEG_CODE32],ax    mov    [SPValueInRealMode], sp; 初始化 16 位代码段描述符    mov    ax, cs    movzx    eax, ax    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; 初始化 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; 初始化堆栈段描述符    xor    eax, eax    mov    ax, ds    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; 为加载 GDTR 作准备    xor    eax, eax    mov    ax, ds    shl    eax, 4    add    eax, LABEL_GDT        ; eax <- gdt 基地址    mov    dword [GdtPtr + 2], eax    ; [GdtPtr + 2] <- gdt 基地址
; 加载 GDTR    lgdt    [GdtPtr]    ; 关中断    cli    ; 打开地址线A20    in    al, 92h    or    al, 00000010b    out    92h, al; 准备切换到保护模式    mov    eax, cr0    or    eax, 1    mov    cr0, eax    ; 真正进入保护模式    jmp    dword SelectorCode32:0    ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0  处
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LABEL_REAL_ENTRY:        ; 从保护模式跳回到实模式就到了这里    mov    ax, cs    mov    ds, ax    mov    es, ax    mov    ss, ax    mov    sp, [SPValueInRealMode]    in    al, 92h        ; `.    and    al, 11111101b    ;  | 关闭 A20 地址线    out    92h, al        ; /    sti            ; 开中断    mov    ax, 4c00h    ; `.    int    21h        ; /  回到 DOS ; END of [SECTION .s16][SECTION .s32]; 32 位代码段. 由实模式跳入.[BITS    32]LABEL_SEG_CODE32:    mov    ax, SelectorData    mov    ds, ax            ; 数据段选择子    mov    ax, SelectorTest    mov    es, ax            ; 测试段选择子    mov    ax, SelectorVideo    mov    gs, ax            ; 视频段选择子    mov    ax, SelectorStack    mov    ss, ax            ; 堆栈段选择子    mov    esp, TopOfStack; 下面显示一个字符串    mov    ah, 0Ch            ; 0000: 黑底    1100: 红字    xor    esi, esi    xor    edi, edi    mov    esi, OffsetPMMessage    ; 源数据偏移    mov    edi, (80 * 10 + 0) * 2    ; 目的数据偏移。屏幕第 10 行, 第 0 列。    cld .1:    lodsb                        ;lodsb,lodsw 把DS:SI指向的存储单元中的数据装入AL或AX,然后根据DF标志增减SI    test    al, al                ;test指令这类指令主要影响 ZF 标志位;                                ;test ax,100b  将 ax的 值  和 100b进行“与”操作 ,但不改变ax本身;若与操作的结果为零则ZF置位。    jz    .2    mov    [gs:edi], ax    add    edi, 2    jmp    .1 .2:    ; 显示完毕    call    DispReturn    call    TestRead    call    TestWrite    call    TestRead    ; 到此停止    jmp    SelectorCode16: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    jz    .2    mov    [es:edi], al    inc    edi    jmp    .1.2:    pop    edi    pop    esi    ret ; TestWrite 结束----------------------------------------------------------; ------------------------------------------------------------------------; 显示 AL 中的数字; 默认地:;    数字已经存在 AL 中;    edi 始终指向要显示的下一个字符的位置; 被改变的寄存器:;    ax, edi; ------------------------------------------------------------------------DispAL:    push    ecx    push    edx    mov    ah, 0Ch            ; 0000: 黑底    1100: 红字    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 结束-------------------------------------------------------------; ------------------------------------------------------------------------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 结束---------------------------------------------------------SegCode32Len    equ    $ - LABEL_SEG_CODE32; END of [SECTION .s32]; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式[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, eaxLABEL_GO_BACK_TO_REAL:    jmp    0:LABEL_REAL_ENTRY    ; 段地址会在程序开始处被设置成正确的值
Code16Len    equ    $ - LABEL_SEG_CODE16; END of [SECTION .s16code]

 

转载于:https://www.cnblogs.com/pacoson/p/4622804.html

你可能感兴趣的文章
Visual Studio 11增强支持的标准 C++11 介绍
查看>>
C++ 运算符优先级
查看>>
codechef Chef and Problems
查看>>
6-3-二叉树(三叉链表存储)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版...
查看>>
display:inline-block的div 与 display:block的div之间有间隔问题(div与div之间有间隔的可能性)...
查看>>
supervisor简明教程
查看>>
【以前的空间】bzoj1009 [HNOI2008]GT考试
查看>>
安装vs2017后,RDLC 报表定义具有无法升级的无效目标命名空间
查看>>
pycharm 2016.2注册码
查看>>
SqlServer常用命令
查看>>
匿名函数中undefined形参疑问(转载)
查看>>
如何让EditText不能自动获取焦点(转)
查看>>
一个小小的百度贴吧爬虫(Python)
查看>>
Solaris - 修改IP和主机名
查看>>
html5中的选择器
查看>>
WinStore控件之TextBox
查看>>
oracle dmp文件的导入导出
查看>>
#assign# 宽动态成像
查看>>
iOS背景图片大小不一致问题
查看>>
maven、spring jdbc 与mysql
查看>>