austgl / writeos

Automatically exported from code.google.com/p/writeos
0 stars 0 forks source link

chapter3/1/loader.S #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
为了加深理解,我想对比一下16位和32位程序之间的差异,如�
��理解的不对,请不吝
指出。以下
第一个例子是我写的一个基于16位操作的例子,第二个是书上
的例子(chapter3/1
/loader.S)。

1、16位的例子(在第15行第10位显示welcome字符串):
.MODEL small
.386
.DATA
MSG1    db  'Welcome...'
Count   EQU $-MSG1
.CODE
=============================================================================
;标号A 
======================================================================
.startup 
MOV AX, 0B800H
MOV ES,AX

=============================================================================
;标号B 
======================================================================
MOV DI, 15
IMUL DI, 160
MOV Cx, 10
SHL Cx, 1
ADD DI, CX
MOV CX, Count
LEA SI, MSG1
MOV AH,0EH
.REPEAT
LODSB
STOSW
.UNTILCXZ

=============================================================================
;标号C 
======================================================================
.exit 0
end

2、书上的例子:

#include "pm.h"

.code16
.text
    jmp LABEL_BEGIN     /* jump over the .data section. */

LABEL_GDT:          Descriptor  0,                        0, 0
LABEL_DESC_CODE32:  Descriptor  0,       (SegCode32Len - 1), (DA_C + DA_32)
LABEL_DESC_VIDEO:   Descriptor  0xB8000,             0xffff, DA_DRW

.set GdtLen, (. - LABEL_GDT)  /* GDT Length */

GdtPtr: .2byte  (GdtLen - 1)  /* GDT Limit */
        .4byte  0             /* GDT Base */

/* GDT Selector */
.set    SelectorCode32, (LABEL_DESC_CODE32 - LABEL_GDT)
.set    SelectorVideo,  (LABEL_DESC_VIDEO  - LABEL_GDT)

=============================================================================
;标号1 
======================================================================
/* Program starts here. */
LABEL_BEGIN:
    mov     %cs, %ax    /* Move code segment address(CS) to data segment */
    mov     %ax, %ds    /* register(DS), ES and SS. Because we have      */
    mov     %ax, %es    /* embedded .data section into .code section in  */
    mov     %ax, %ss    /* the start(metioned in the NOTE above).        */

    mov     $0x100, %sp

    /* Initialize 32-bits code segment descriptor. */
    xor     %eax, %eax
    mov     %cs, %ax
    shl     $4, %eax
    addl    $(LABEL_SEG_CODE32), %eax
    movw    %ax, (LABEL_DESC_CODE32 + 2)
    shr     $16, %eax
    movb    %al, (LABEL_DESC_CODE32 + 4)
    movb    %ah, (LABEL_DESC_CODE32 + 7)

    /* Prepared for loading GDTR */
    xor     %eax, %eax
    mov     %ds, %ax
    shl     $4, %eax
    add     $(LABEL_GDT), %eax      /* eax <- gdt base*/
    movl    %eax, (GdtPtr + 2)

    /* Load GDTR(Global Descriptor Table Register) */
    lgdtw   GdtPtr

=============================================================================
;标号2 
======================================================================
    /* Clear Interrupt Flags */
    cli

    /* Open A20 line. */
    inb     $0x92, %al
    orb     $0b00000010, %al
    outb    %al, $0x92

    /* Enable protect mode, PE bit of CR0. */
    movl    %cr0, %eax
    orl     $1, %eax
    movl    %eax, %cr0

    /* Mixed-Size Jump. */
    ljmpl $SelectorCode32, $0       /* Thanks to earthengine@gmail, I got */
                                    /* this mixed-size jump insn of gas.  */

=============================================================================
;标号3 
======================================================================
LABEL_SEG_CODE32: 
.code32
    mov     $(SelectorVideo), %ax
    mov     %ax, %gs                /* Video segment selector(dest) */

    movl    $((80 * 10 + 0) * 2), %edi
    movb    $0xC, %ah               /* 0000: Black Back 1100: Red Front */
    movb    $'P', %al

    mov     %ax, %gs:(%edi)

=============================================================================
;标号4 
======================================================================
    /* Stop here, infinate loop. */
    jmp     .

/* Get the length of 32-bit segment code. */
.set    SegCode32Len, . - LABEL_SEG_CODE32

第一个例子“标号A-标号B”之间是段地址的初始化操作,跟��
�二个例子“标号1-标号2”
之间的内容
作用一样。

第一个例子“标号B-标号C”之间是字符串显示的操作,跟第��
�个例子“标号3-标号4”之
间的内容作用
一样。

第一个例子“标号C-最后”之间的是结束语句,跟第二个例子
“标号4-最后”之间的内容
作用一样。

第二个例子“标号2-标号3”之间的内容作用是进入“保护模��
�”,是32位特有的。

我的理解对吗?

Original issue reported on code.google.com by linux...@gmail.com on 25 Sep 2008 at 5:44

GoogleCodeExporter commented 9 years ago
“标号2-标号3”之间内容仍然是 16 位的代码段,不是什么 32 
位特有的。
汇编伪指令是基本不区分 16 位和 32 
位程序的,但是同一条汇编语句最后
形成的机器指令在 16 位和 32 位下有区别。

Original comment by solrex on 26 Sep 2008 at 12:15