能力值:
( LV2,RANK:10 )
7 楼
呵呵,我初学者不懂,请见谅,如果可以的话最好不过了,实在不行的话,用其它的编译器也可以接受的啊^_^
能力值:
(RANK:260 )
8 楼
其实这个事说简单也简单,如果对汇编和opcode有一定了解的话;说麻烦也挺麻烦,因为VC等编译器不支持生成16位代码,而Turbo C这样的编译器又不支持生成32位代码。
不过毕竟我们要生成DOS程序,32位代码只完成一个很小的功能,所以还是选择用DOS下的16位编译器,而对32位代码采取一些opcode hack的技巧了。
大体过程如下:建立保护模式必要的数据结构,主要指GDT,而IDT呢,我们不打算搞得复杂,所以不打算在保护模式下打开中断,就不用了。
GDT建好后,载入GDTR这个寄存器,然后置CPU中CR0的PE位,再用一个near Jmp将预取指令队列flush一下,我们就进入保护模式了。
返回实模式就清除CR0中的PE位即可。
对了,如果要访问1M以上的内存,需要打开A20;如果不访问内存,不打开A20也没有影响。
这个
4GMEM.zip
是梁肇新先生写的一个程序,在DOS下进入保护模式,给FS装入4GB的limit,然后再返回到实模式下。于是,借助于FS段,以及0x66,0x67前缀,实现了在DOS下对4GB地址空间的访问能力。
参考这个程序,相信你就可以完成自己的程序了。在保护模式下,直接写入显存,即0xB8000,即可实现字符串的输出。
对了,这个程序是在Turbo C下测试成功的,要在纯DOS环境运行,不能在Windows下的ntvdm环境下运行的。
上传的附件:
能力值:
( LV2,RANK:10 )
9 楼
谢谢---书呆彭---的回复,我想你说的---对32位代码采取一些opcode hack的技巧---这个32位代码量小的话可以这样用,如果32位的代码量大,这样用是不是有些...?---才看C,可能我的理解不对(用汇编我能实现这些)
能力值:
(RANK:260 )
10 楼
代码量大当然可以用C来写,但是我不知道如何将16位代码和32位代码链接在一起,也不知道在C中如何交叉调用,比如16位调用32位函数。
所以,至少还需要一部分opcode hack来做交叉引用的代理。 其实,更好的办法是像OSLoader一样,16位代码和32位代码写成两个模块,用16位代码加载32位的程序到内存中,完成必要的初始化后直接将控制转移给纯32位代码。当然,要加载程序入内存需要对可执行文件的格式非常熟悉。
能力值:
( LV2,RANK:10 )
13 楼
我把汇编的代码帖上来了,求懂C的高手来帮我转成C语言形式的,或者C内嵌汇编的也行,感激不尽了!!!
.386P
CSEG16 SEGMENT USE16
ASSUME CS:CSEG16
ORG 100H
START: cli
mov bx,offset cs:xianshixinxi_16
mov di,20*2
call xianshi_16
xor eax,eax
mov ax,cs
mov word ptr cs:seg_offset_16+2,ax
shl eax,4
xor ebx,ebx
mov bx,SEG CSEG_P32
SHL EBX,4
mov word ptr cs:cs_SEL32+2,bx
shr ebx,16
mov byte ptr cs:cs_SEL32+4,bl
xor ebx,ebx
mov bx,SEG CSEG_P16
SHL EBX,4
mov word ptr cs:cs_SEL16+2,bx
shr ebx,16
mov byte ptr cs:cs_SEL16+4,bl
xor edx,edx
mov dx,offset cs:gdt0
add eax,edx
mov dword ptr cs:GDTR+2,eax
LGDT qword ptr cs:GDTR ;这里使用qword是masm5.0编译器的bug,其它的masm6.xx编译器需要改为fword
mov eax,cr0
or al,1
mov cr0,eax
db 0eah
seg_offset_16_P32: dw 0
dw offset cs_SEL32 - offset gdt0
xianshixinxi_16_dos_prog:
mov bx,offset cs:xianshixinxi_16_dos
mov di,80*2*3+20*2
call xianshi_16
return_dos:
mov ah,4ch
int 21h
xianshi_16:
mov ax,0b800h
mov es,ax
mov dh,0F4h
XIANSHI_16_1:
mov dl,cs:[bx]
cmp dl,0
je xianshi_over_16
mov word ptr es:[di],dx
add di,2
inc bx
jmp XIANSHI_16_1
xianshi_over_16: ret
;--------------------------------------------------------------------------------------------------------
gdt0: DQ 0
cs_SEL32: dw 0ffffh,0000,9a00h,00CFh
cs_SEL16: dw 0ffffh,0000,9a00h,0080h
DATA_SEL32: dw 0ffffh,0000,9200h,00CFh
GDTR: DW $-gdt0-1,0,0
;----------------------------------------------------------------------------------------
xianshixinxi_16 db "HELLO WORLD_DOS_16",0
xianshixinxi_16_dos db "RETURN DOS---QQ GROUP:67286087;QQ:750347821;EMAIL:750347821@QQ.COM NAME:CXDZXC Address:LANZHOU DATE:2009
-3-15 ",0
;----------------------------------------------------------------------------------------
CSEG16 ENDS
;-------------------------------------------------------------------------------------------------------
CSEG_P32 SEGMENT USE32
assume CS:CSEG_P32
MOV dx,DATA_SEL32 - gdt0
MOV es,dx
mov edi,0b8000h+80*2*1+20*2
XOR EBX,EBX
mov Ebx,offset cs:xianshixinxi_P32
mov dh,0F4h
xianshi_P32:
mov dl,cs:[ebx]
cmp dl,0
je xianshi_over_P32
mov word ptr es:[edi],dx
add edi,2
inc ebx
jmp xianshi_P32
xianshi_over_P32:
db 0eah
SEL_offset_P32_P16: dw 0,0,offset cs_SEL16 - offset gdt0
;----------------------------------------------------------------------------------------
xianshixinxi_P32 db "HELLO WORLD_P32",0
;----------------------------------------------------------------------------------------
CSEG_P32 ENDS
;-------------------------------------------------------------------------------------------------------
CSEG_P16 SEGMENT USE16
assume CS:CSEG_P16
mov edi,0b8000h+80*2*2+20*2
XOR EBX,EBX
mov bx,offset cs:xianshixinxi_P16
mov dh,0F4h
xianshi_P16:
mov dl,cs:[ebx]
cmp dl,0
je xianshi_over_P16
mov word ptr es:[edi],dx
add edi,2
inc ebx
jmp xianshi_P16
xianshi_over_P16:
mov eax,cr0
AND al,0FEH
mov cr0,eax
db 0eah
seg_offset_16: dw offset xianshixinxi_16_dos_prog,0
;----------------------------------------------------------------------------------------
xianshixinxi_P16 db "HELLO WORLD_P16",0
;----------------------------------------------------------------------------------------
CSEG_P16 ENDS
END START
能力值:
( LV2,RANK:10 )
15 楼
WIN32程序中都有段,This program cannot be run in DOS,其实这就是段DOS程序代码,在VC中是可以用真的DOS程序替换的,This program cannot be run in DOS只是VC默认嵌入的DOS程序,用TC编译一个DOS程序,然后在VC中设置好嵌入就行了,详细GOOGLE一下,就OK啦