![]() |
China DOS Union-- Unite DOS · Advance DOS · Grow DOS --Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum |
| Guest | Log in | Register | Members | Search | China DOS Union |
|
中国DOS联盟论坛 The time now is 2026-09-15 05:37 |
47,812 topics / 349,917 posts / today 0 new / 48,268 members |
| DOS开发编程 & 发展交流 (开发室) » [Help] How can I break through 640K in DOS real mode? |
| Printable Version 1,946 / 6 |
| Floor1 crscd | Posted 2003-07-15 00:00 |
| 初级用户 Posts 4 Credits 116 | |
|
I’m developing an application that runs under DOS real mode, but the executable SIZE is 700K, so it can’t run in DOS real mode. What measures can I take to reduce the executable SIZE, or how can I break through the real-mode limits, and how can I use the extended memory between 640K and 1M? Thanks!!!
|
|
| Floor2 garychang | Posted 2003-07-16 00:00 |
| 初级用户 Posts 9 Credits 136 | |
|
Just switch into protected mode.
|
|
| Floor3 Dark-Destroy | Posted 2003-07-16 00:00 |
| 元老会员 Posts 3,551 Credits 8,312 | |
|
There’s another way too, use XMS
|
|
| Floor4 Roy | Posted 2003-07-16 00:00 |
| 管理员 Posts 1,633 Credits 4,869 | |
|
There are also DPMI, VCPI, and EMS...
|
|
| Floor5 Dark-Destroy | Posted 2003-07-16 00:00 |
| 元老会员 Posts 3,551 Credits 8,312 | |
|
No one uses EMS anymore now, right.....
|
|
| Floor6 crscd | Posted 2003-07-21 00:00 |
| 初级用户 Posts 4 Credits 116 | |
| Floor7 凌晨一点 | Posted 2003-10-25 00:00 |
| 初级用户 Posts 54 Credits 255 | |
|
Method for directly accessing image data in XMS under real mode
Directly access 4GB of memory Whether the CPU is in real mode or protected mode, the formation of its physical address uses the segment descriptor registers. For the CPU when forming physical addresses, real mode and ring-0 non-paged protected mode are the same. The only difference is in how the segment base address and segment limit are set. After the CPU is reset, the CPU is in real mode, and the limit value of the segment descriptor registers is automatically set to 64KB. The base address of the segment descriptor registers can be set through assignments to the segment registers, but at most it can only be set to FFFFH×16. Therefore, the address space within a segment can only be 64KB, and the memory space the CPU can access can only be FFFFH×16+64KB. Based on the uniformity of CPU physical address formation ,, the key to directly accessing 4GB of memory in real mode is to enlarge the limit value of the segment descriptor registers. This allows 32-bit register indirect addressing operations in instructions such as “MOV AX,” to access 4GB of memory. However, in real mode the CPU does not provide any instruction to change the limit value of the segment descriptor registers. The contents of the segment descriptor registers can only be changed in protected mode. When the PE bit of control register CR0 is set to 1, the CPU enters protected mode; when the PE bit of control register CR0 is set to 0, the CPU returns to real mode. When the working mode is changed by setting CR0, the contents of the segment descriptor registers do not change. Therefore, before directly accessing 4GB of memory in DOS real mode, let the CPU enter protected mode, and load segment descriptors with a 4GB limit into the segment descriptor registers DS, ES, FS, and GS. Then return to real mode. This will allow 32-bit register indirect addressing operations in instructions such as “MOV AX,” and “MOV AX,FS:” to access 4GB of memory. Since what this programming method produces is an executable based on real mode, it cannot run in protected mode or virtual 8086 mode; that is, it cannot run under Windows, nor can an EMS memory driver (such as EMM386.EXE) be loaded in the DOS system. Programming method (1)Programming environment This article uses the Borland C++ 3.1 programming environment, and specific operations in the program are implemented with inline assembly. In Options “Compile”-“Advanced Code generation”, select the 386 instruction set. Since the internal compiler in the integrated development environment cannot recognize inline 386 assembly instructions, to use assembly instructions with 32-bit registers and 32-bit address operations, you can have the integrated development environment call TASM.EXE for compilation, that is, set Options “Compile”-“Code generation”-“Compile via assemler” to ON. This way, the 386 assembly instructions can be used completely, and this compilation method is used in the programming examples below. (2)Basic operation functions ①Open the A20 address line To access 4GB of memory, the A20 address line must be opened. void openA20() { while(inp(0x64) & 2); outp(0x64,0xd1); while(inp(0x64) & 2); outp(0x60,0xdf); while(inp(0x64) & 2); outp(0x64,0xff); } ②Function for setting a 4GB limit for the data segment First, establish a global descriptor table GDT, namely GDT_def, which contains two descriptors. The first is a null descriptor (required by the system in protected mode), and the second is a data segment descriptor with a 4GB segment limit. Its selector is 8. Then calculate the base address and length of the GDT and store them in GDT_Addr. Next, load the GDT, enter protected mode, and assign selector 8 to FS and GS. At this time, the second data segment descriptor is loaded into the descriptor registers of FS and GS. Finally return to real mode. By the same reasoning, the 4GB limits of DS and ES can also be set. unsigned long GDT_def={0,0,0x0000FFFF,0x008F9200}; //global descriptor table GDT unsigned char GDT_Addr={0}; //stores the base address and length of the GDT void set4gb( ) { asm{ cli //disable interrupts mov word ptr GDT_Addr, (2*8-1) //store the length of the GDT into GDT_Addr mov eax, ds //calculate bits 31-0 of the linear base address of the GDT descriptor table shl eax, 4 //segment address eax=ds×16 xor ebx, ebx //clear ebx mov bx, offset GDT_def //bx=the offset address of GDT_def add eax,ebx //linear base address of the GDT=eax+ebx mov dword ptr GDT_Addr, eax //store the linear base address of the GDT into GDT_Addr lgdt fword ptr GDT_Addr //load GDT_Addr into the GDTR register mov bx, 8 //set the selector for the data segment descriptor mov eax, cr0 or al,1 mov cr0,eax //set the PE bit of CR0 = 1 jmp flush1 //enter protected mode } flush1: asm{ mov fs,bx //load into FS the data segment descriptor with a 4GB limit mov gs,bx //load into GS the data segment descriptor with a 4GB limit and al,0feh mov cr0,eax //set the PE bit of CR0 = 0 jmp flush2 //return to real mode } flush2: asm{ mov ax, 0 mov fs,ax //set the base address of the FS descriptor to 0 mov gs,ax //set the base address of the GS descriptor to 0 sti //enable interrupts } } ③Programming example for directly accessing 4GB memory After FS and GS have a 4GB access limit, 4GB memory access can be achieved through instructions that use 32-bit register indirect addressing. For example, the computation function for image binarization is as follows: void two_mem(unsigned long addrd, unsigned long addrs, unsigned long leng, unsigned char yuzi) { asm mov ecx, leng //leng is the byte count of the image data block asm mov esi, addrs //addrs is the 32-bit linear base address of the source image data block asm mov edi, addrd //addrd is the 32-bit linear base address of the binarized image data block asm mov ah, yuzi //yuzi is the threshold TN0: asm cmp fs:, ah //compare source image data with the threshold asm mov al, 0 //if the source image data<threshold, al=0 asm jc TN1 asm mov al, 255 //if the source image data≥threshold, al=255 TN1: asm mov fs:, al //store the result into the binarized data block asm inc esi //increment the 32-bit linear address of the source image data block by one asm inc edi //increment the 32-bit linear address of the binarized image data block by one asm loopd TN0 } ④Program structure void main( ) { openA20( ); set4gb( ); … … //user program } It’s already been two or three months since you made the post, so I don’t know whether this is still of any use ^_^ |
|
|
[ Contact the Union admin team -
中国DOS联盟 -
Standard version ] Sponsored by ifanr Inc | © 2001–2023 |