Closed GoogleCodeExporter closed 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
linux...@gmail.com
“标号2-标号3”之间内容仍然是 16 位的代码段,不是什么 32 位特有的。 汇编伪指令是基本不区分 16 位和 32 位程序的,但是同一条汇编语句最后 形成的机器指令在 16 位和 32 位下有区别。
Original comment by solrex on 26 Sep 2008 at 12:15
solrex
Original issue reported on code.google.com by
linux...@gmail.com
on 25 Sep 2008 at 5:44