![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-03 01:03 |
共 47,813 主题排行 / 349,918 发帖 / 今日 0 篇 / 48,279 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » 内嵌入汇编,tc编译问题 |
| 可打印版本 1,360 / 3 |
| 第1楼 beiyuly | 发表于 2007-04-19 06:39 |
| 初级用户 发帖 40 积分 95 | |
|
内嵌入汇编,tc编译问题 内嵌入汇编,但是指令提示
instructions not enabled 用的是tc3.0 请教是为什么? 代码如下,实模式下访问4G虚拟内存 /**************************************************************/ #include <dos.h> /////////////////////////////////////////////////////// // 4G Memory Access // This Program Can Access 4G Bytes in DOS Real //Mode,Needn't in Protection Mode It Works. // The Program Enter 32 Bit Flat Mode a moment and //Only Load FS a 32 Bit Flat Mode Selector,Then Return //Real Mode. // Used The FS Can Access All 4G Memory till It be //reloaded. // --By Southern. 1995.7.17 /////////////////////////////////////////////////////// unsigned long GDT_Table[]= { 0,0, //NULL - 00H 0x0000FFFF,0x00CF9A00, //Code32 - 08H Base=0 Limit=4G-1 Size=4G 0x0000FFFF,0x00CF9200 //Data32 - 10H Base=0 Limit=4G-1 Size=4G }; unsigned char OldIDT[6]={0}; //Save The IDTR before Enter Protect Mode. unsigned char pdescr_tmp[6]={0}; //NULL The IDTR,IDTR's Limit=0 will //disable all Interrupts,include NMI. #define KeyWait() {while(inportb(0x64)&2);} void A20Enable(void) { KeyWait(); outportb(0x64,0xD1); KeyWait(); outportb(0x60,0xDF); //Enable A20 with 8042. KeyWait(); outportb(0x64,0xFF); KeyWait(); } void LoadFSLimit4G(void) { A20Enable(); //Enable A20 //************************************** //* Disable ints & Null IDT * //************************************** asm { CLI //Disable inerrupts SIDT OldIDT //Save OLD IDTR LIDT pdescr_tmp //Set up empty IDT.Disable any interrupts, } //Include NMI. //*************************************** //* Load GDTR * //*************************************** asm { //The right Code is Real,But BC++'s Linker NOT Work with 32-bits Code. db 0x66 //32 bit Operation Prefix in 16 Bit DOS. MOV CX,DS //MOV ECX,DS db 0x66 //Get Data segment physical Address SHL CX,4 //SHL ECX,4 MOV word ptr pdescr_tmp[0],(3*8-1) //MOV word ptr pdescr_tmp[0],(3*8-1) db 0x66 XOR AX,AX //XOR EAX,EAX MOV AX,offset GDT_Table //MOV AX,offset GDT_Table db 0x66 ADD AX,CX //ADD EAX,ECX MOV word ptr pdescr_tmp[2],AX //GDTR Base high16 bits db 0x66 SHR AX,16 //SHR EAX,16 MOV word ptr pdescr_tmp[4],AX //GDTR Base high16 bits LGDT pdescr_tmp //Load GDTR } //************************************** //* Enter 32 bit Flat Protected Mode * //************************************** // Set CR0 Bit-0 to 1 Enter 32 Bit Protection //Mode,And NOT Clear machine perform cache,It Meaning //the after Code HAD Ready To RUN in 32 Bit Flat Mode, //Then Load Flat Selector to FS and Description into it's //Shadow register,After that,ShutDown Protection Mode //And ReEnter Real Mode immediately. // The FS holds Base=0 Size=4G Description and //it can Work in Real Mode as same as Pretect Mode, //untill FS be reloaded. // In that time All the other Segment Registers are //Not Changed,except FS.(They are ERROR Value holded in CPU). asm { MOV DX,0x10 //The Data32 Selector db 0x66,0x0F,0x20,0xC0 //MOV EAX,CR0 db 0x66 MOV BX,AX //MOV EBX,EAX OR AX,1 db 0x66,0x0F,0x22,0xC0 //MOV CR0,EAX //Set Protection enable bit JMP Flush } //Clear machine perform cache. Flush: //Now In Flat Mode,But The CS is Real Mode Value. asm { //And it's attrib is 16-Bit Code Segment. db 0x66 MOV AX,BX //MOV EAX,EBX db 0x8E,0xE2 //MOV FS,DX //Load FS now db 0x66,0x0F,0x22,0xC0 //MOV CR0,EAX //Return Real Mode.Now FS's Base=0 Size=4G LIDT OldIDT //LIDT OldIDT //Restore IDTR STI //STI //Enable INTR } } //With FS can Access All 4G Memory Now.But if FS be reloaded in Real Mode //It's Limit will Be Set to FFFFh(Size=64K),then Can not used it to Access //4G bytes Memory Again,Because FS is Segment:Offset Memory type after that. //If Use it to Access large than 64K will generate Execption 0D. unsigned char ReadByte(unsigned long Address) { asm db 0x66 asm mov di,word ptr Address //MOV EDI,Address asm db 0x67 //32 bit Address Prefix asm db 0x64 //FS: asm mov al,byte ptr [BX] //=MOV AL,FS:[EDI] return _AL; } unsigned char WriteByte(unsigned long Address) { asm db 0x66 asm mov di,word ptr Address //MOV EDI,Address asm db 0x67 //32 bit Address Prefix asm db 0x64 //FS: asm mov byte ptr [BX],al //=MOV FS:[EDI],AL return _AL; } ///////////////// Don't Touch Above Code /////////////// //////////////////////////////////////////////////////// #include <stdio.h> void Dump4G(unsigned long Address) { int i; int j; for(i=0;i<20;i++) { printf("%08lX: ",(Address+i*16)); for(j=0;j<16;j++) printf("%02X ",ReadByte(Address+i*16+j)); printf(" "); for(j=0;j<16;j++) { if(ReadByte(Address+i*16+j)<0x20) printf("."); else printf("%c",ReadByte(Address+i*16+j)); } printf("\n"); } } main() { char KeyBuffer[256]; unsigned long Address=0; unsigned long tmp; LoadFSLimit4G(); printf("====Designed By Southern.1995.7.17====\n"); printf("Now you can Access The Machine All 4G Memory.\n"); printf("Input the Start Memory Physical to DUMP.\n"); printf("Press D to Cuntinue DUMP,0 to End & Quit.\n"); do { printf("-"); gets(KeyBuffer); sscanf(KeyBuffer,"%lX",&tmp); if(KeyBuffer[0]=='q') break; if(KeyBuffer[0]=='d') Address+=(20*16); else Address=tmp; Dump4G(Address); }while(Address!=0); return 0; } |
|
| 第2楼 GOTOmsdos | 发表于 2007-04-19 09:35 |
| 铂金会员 发帖 1,827 积分 5,154 | |
|
访问4G内存,要32位CPU吧?
编译要设成80386 |
|
| 第3楼 beiyuly | 发表于 2007-04-19 23:16 |
| 初级用户 发帖 40 积分 95 | |
|
问题解决了。在编译的时候,用tcc.exe,然后用参数 -1,表示使用80186/286汇编,英文是
80186/286 instructions |
|
| 第4楼 beiyuly | 发表于 2007-04-19 23:17 |
| 初级用户 发帖 40 积分 95 | |
|
具体参数说的是用186/286指令还是不用,没有具体说明
|
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |