Code Comments
Programming Forum and web based access to our favorite programming groups.On Feb 18, 3:09 pm, Alex Buell <spamt...@crayne.org> wrote: > IIRC, that was due to a bug in segmented addressing on the 8086/8088 > processors. You could address the first 64K above the 1MB address range > due to this; but that was many, many years ago and I probably > misremember but I think it's actually something like that. Replace 808x with 80286+ and you're correct. The 808x didn't have enough address lines for this trick to work; the 286 and later did. (80186 *might* have, but I don't have the sheets in front of me atm to confirm)
Post Follow-up to this messageHello! Is UNREAL MODE i386 assembler? Because I haven't seen the specific way of how the offset registers (16bits) can access the whole 4GB space, if the segment registers are holding the only 1 descriptor with the flat memory and cannot be changed. So, maybe it is i386 assembler with the new larger 32bit offset registers? or maybe the user must change the descriptor entry each time to access upper memories? Having 4096 descriptor entries of 64KB each, the old i86 assembler could have accessed 256MB of memory. 4096 descriptor entries are 32KB. Greetings, H.Samso
Post Follow-up to this message"SoLo2" <spamtrap@crayne.org> wrote in message news:d97b55a5-f121-4e30-b13d-9aeec83141d7@d4g2000prg.googlegroups.com... > Is UNREAL MODE i386 assembler? That's possible but not necessary. You can use most i386 (and above) instructions to get 32-bit operations in real or unreal modes with the appropriate prefix. The ones you can't use only make sense in protected mode. > Because I haven't seen the specific > way of how the offset registers (16bits) > can access the whole 4GB space, if the > segment registers are holding the only > 1 descriptor with the flat memory and > cannot be changed. > > So, maybe it is i386 assembler with the > new larger 32bit offset registers? No; a segment in real or unreal modes is only 64kB because only the low 16 bits in the offset are used; any high bits are ignored. The only difference is that in unreal mode you can place your segments arbitrarily in memory, via the LDT/GDT, instead of having them all overlapping in the first 1MB of memory as in real mode. > or maybe the user must change the descriptor > entry each time to access upper memories? > > Having 4096 descriptor entries of 64KB > each, the old i86 assembler could have > accessed 256MB of memory. Real mode assembly doesn't have descriptors; the 64kB segments are defined as being at sequential intervals of 16 bytes, giving you no more than 1MB (+64kB if A20 is active) of accessible RAM. Unreal mode basically consists of setting the descriptors in protected mode and then switching back to real mode. I don't know if it was intentional, but the CPU will continue interpreting DS, CS, SS, etc. as selectors instead of reverting to real-mode segments. Since the 8086 didn't have protected mode, you can't enter unreal mode. IIRC, you couldn't on an i286 either because there was no way to get out of protected mode without resetting the processor. S -- Stephen Sprunk "God does not play dice." --Albert Einstein CCIE #3723 "God is an inveterate gambler, and He throws the K5SSS dice at every possible opportunity." --Stephen Hawking
Post Follow-up to this messageOn Tue, 19 Feb 2008 14:25:39 -0800 (PST), Terence <spamtrap@crayne.org> wrote: >Ah! You spoilt youngsters! >I remember when we thought having 4k bytes was wonderful, after using >50 word drums... I fondly remember when my schools 1401 was upgraded from 8,000 chars to 12,000. It was needed to run the Fortran compiler (also the schools production work). Just about 40 years ago. :-) -- ArarghMail802 at [drop the 'http://www.' from ->] http://www.arargh.com BCET Basic Compiler Page: http://www.arargh.com/basic/index.html To reply by email, remove the extra stuff from the reply address.
Post Follow-up to this messageElcaro Nosille wrote: > Would it be possible to use a 32-bit addressing-mode in real-mode via > address-size prefix and thereby to have segments which are 4GB long? Data segments, yes. In real mode, we're using ip and sp, not eip and esp, so these need to be kept "low". > Someone in a different NG claimed that he can address more than 1MB > in real-mode with the large addressing-modes. The time I dealt with > such things is 15 years ago and the only way to have segments which > are 4GB long is to switch into 32 bit protected-mode, load the seg- > ment registers from appropriate selectors and to get back into real > -mode with interrupts disabled to prevent the cached selectors to > be overwritten. Need interrupts disabled for the brief time you're in pmode, but once back in real mode, we can enable 'em. The only thing that will alter the "limit" is going back to pmode and reloading the selector. An ISR might do this (never seen it). Running djgpp-Nasm *does* do it (and leaves junk in the high word of 32-bit regs, too!). In order to avoid potential problems with this, install the "relimiter" code as a handler for the segment overrun exception... Like Herman Dullink's code, here: <http://www.programmersheaven.com/do...4/download.aspx> I've "translated" Herman's code to Nasm, and have a few examples. Rock solid, in my experience. This isn't very "convenient" - it needs to be started from real mode, which most folks don't use, these days - gotta reboot to use it. (yes, you need a 386+, and no, you can't do it with 16-bit offset registers) Other than that, it's a wonderful playground! Best, Frank Hell, I'll post an example. This one doesn't actually go over 1 Meg, but it will, trust me. Based on Herman Dullink's code - translation errors are mine... ; Flat Real/Real Big mode ; nasm -f bin -o flattest.com flattest.asm org 100h section .data GDT dw 15 ; Limit (16 bytes) dw GDT,0 ; Offset within current segment... dw 0 ; Unused FLAT_desc dw 0ffffh ; Limit (bit 0..15) db 0,0,0 ; Base (bit 0..23) db 92h ; Access rights db 0cfh ; Page granularity + Limit(16..19) db 0 ; Base (bit 24..31) FLAT_sel equ FLAT_desc - GDT old_IRQ5 dd 0 last_Exc_13 dd 0 IRQ5_flag db 0 message db ' Message written using direct screen writing' db ' & 32-bit offsets in REAL-mode!! ' no_NT_msg db 'This program requires at least an i386sx!',10,'$' V86_msg db 'Cannot run in a virtual environment!',10,'$' SOE_msg db 'Segment Overrun Exception!',10,'$' allocerrmsg db 'Allocation error!',0Dh,0Ah,0,'$' [section .text] call FLAT_install ; Enable 4Gb address space ; mov ax,3 ; Colour text mode ; int 10h xor ax,ax ; Base ES <- 000[0000]0h mov es,ax mov ah,1fh ; Colour = White on blue top: mov si,message mov edi,000b8000h ; EDI <- top left screen address mov cx,80 ; Write one line l1: lodsb ; Get a char a32 stosw ; [es:edi] Store char + attrib loop l1 xor ax,ax int 016h ; mov ax,0003h ; int 010h cmp al, 1Bh jnz top exit: call FLAT_destall ; <- Very Important!!! mov ax,04C00h ; return success int 021h ;------------------------------------------------------------------- FLAT_install ; proc ; Installs FLAT_tsr pushf ; Check for NT-flag (only on 386+) pushf pop ax xor ah,40h push ax popf pushf pop bx popf cmp ah,bh jne no_NT ; SMSW is a priviledged instruction(?) smsw ax ; Check for real mode test al,1 jnz short V86 pushf ; Save flags & DS register push ds cli xor eax,eax ; Get IRQ5 vector & Set FLAT_tsr mov ds,ax mov ebx,[ds:34h] mov [cs:old_IRQ5],ebx mov dword [ds:34h],FLAT_tsr mov ax,cs mov [ds:36h],ax shl eax,4 ; Build Global Descriptor Table add dword [cs:GDT+2],eax pop ds ; Restore DS register & flags popf ret no_NT: mov ah,09h ; Write message mov dx,no_NT_msg push cs pop ds int 21h mov ax,4C01h ; Terminate with error code 1 int 21h V86: mov ah,09h ; Write message mov dx,V86_msg push cs pop ds int 21h mov ax,4C02h ; Terminate with error code 2 int 21h ;-------------------------------------------------------------------------- FLAT_destall ; proc ; Destalls FLAT_tsr push ds ; Save DS register xor ax,ax ; Restore old IRQ5 vector mov ds,ax mov eax,[cs:old_IRQ5] mov [ds:34h],eax pop ds ; Restore DS register ret ;------------------------------------------------------------------------ FLAT_tsr ; proc test byte[cs:IRQ5_flag],01h ; Exception within IRQ5 handler? jnz short Exc_13 push ax ; Ask PIC if IRQ5 is 'IN-SERVICE' mov al,0Bh out 20h,al jmp $+2 in al,20h test al,20h pop ax jz short Exc_13 IRQ5: mov byte[cs:IRQ5_flag],1 ; Call old IRQ5 handler pushf call dword [cs:old_IRQ5] mov byte[cs:IRQ5_flag],0 iret Exc_13: push eax ; Save accumulator mov eax,[ss:esp+4] ; Get address of SOE cmp eax,[cs:last_Exc_13] ; Same as last time? je short SOE mov [cs:last_Exc_13],eax lgdt [cs:GDT] ; Load GDT Register push gs push fs push es push ds push bx ; Save registers mov eax,CR0 or al,1 ; Enter Protected mode mov CR0,eax jmp $+2 mov bx,FLAT_sel ; Load 4Gb limits mov ds,bx mov es,bx mov fs,bx mov gs,bx and al,0FEh ; Back to Real mode mov CR0,eax pop bx pop ds pop es pop fs pop gs ; Restore registers ; mov al, 'X' ; int 29h pop eax ; Restore accumulator iret ; Done SOE: call FLAT_destall ; Remove FLAT_tsr mov ah,0fh ; Clear screen int 10h mov ah,00h int 10h mov ah,09h ; Write message mov dx,SOE_msg push cs pop ds int 21h mov ax,4C0Dh ; Terminate with error code 13 int 21h
Post Follow-up to this messageStephen Sprunk wrote: > > No; a segment in real or unreal modes is only 64kB because only the low > 16 bits in the offset are used; any high bits are ignored. The only > difference is that in unreal mode you can place your segments > arbitrarily in memory, via the LDT/GDT, instead of having them all > overlapping in the first 1MB of memory as in real mode. > That is incorrect. "Unreal mode" is about changing the segment limits, returning to real mode, and then use address size overrides to access high memory. > > Real mode assembly doesn't have descriptors; the 64kB segments are > defined as being at sequential intervals of 16 bytes, giving you no more > than 1MB (+64kB if A20 is active) of accessible RAM. > > Unreal mode basically consists of setting the descriptors in protected > mode and then switching back to real mode. I don't know if it was > intentional, but the CPU will continue interpreting DS, CS, SS, etc. as > selectors instead of reverting to real-mode segments. > That is also incorrect. The CPU will not reset the limit field of the hidden descriptor register; however, the CPU will NOT interpret segment selectors once back in real mode - loading a value into a segment register back in real mode will set its base to (value << 4) just as before. The limit field, however, is never touched, so it will stay at what it last was in protected mode. -hpa
Post Follow-up to this messageAm Tue, 19 Feb 2008 16:42:10 +0100 schrieb Wolfgang Kern: I am the one, who talk with Elcaro Nosille. The beginning of that discurs is Elcaros statement, that we need an 64bit-mode to adress linear. I answer, that it is also possible with the 16bit-adressmode(first without specifying if i ment in PM or RM). Beside that statement i offer the Unrealmode. But i think there is a little misinterpretation, that i use the Unrealmode with the 32bit-adressmode. I only use it with the 16bit-adressmode, to adress linear the hole 4GB-adressspace and also handel with IRQs and softints of the DOS/BIOS enviroment. > Unreal/Bigreal will crash > on any IRQ if the handlers weren't written explicite for it. I always enable IRQs after i switch to the Unrealmode leaving 16Bit-adressmode. No crash occur, when i use Softints. So only the 32Bit-adressmode need in both ways(for PM and RM), an explicite written handler. Into the Unrealmode there is no problem to relaod an extended segment with an other segmentadress, also as H. Peter Anvin discribe: "The CPU will not reset the limit field of the hidden descriptor register; however, the CPU will NOT interpret segment selectors once back in real mode - loading a value into a segment register back in real mode will set its base to (value << 4) just as before. The limit field, however, is never touched, so it will stay at what it last was in protected mode." Dirk
Post Follow-up to this messageDirk Wolfgang Glomp wrote: > > > I always enable IRQs after i switch to the Unrealmode leaving > 16Bit-adressmode. No crash occur, when i use Softints. So only the > 32Bit-adressmode need in both ways(for PM and RM), an explicite written > handler. > The problem is that if any interrupt handler ever goes in the PM, it will destroy unreal mode on return (there is, unfortunately, no sane way to read out the segment limits so they can be restored.) So you're playing a gamble with the underlying platform. What's better, IMNSHO, is to stay in protected mode, and intercept interrupts and drop back into (normal) real mode for those. -hpa
Post Follow-up to this messageAm Wed, 20 Feb 2008 13:53:45 -0800 schrieb H. Peter Anvin: > Dirk Wolfgang Glomp wrote: > > The problem is that if any interrupt handler ever goes in the PM, it > will destroy unreal mode on return (there is, unfortunately, no sane way > to read out the segment limits so they can be restored.) So you're > playing a gamble with the underlying platform. I didnīt know any normal DOS-IRQ that goes to PM, so only memmorymanager do that? Dirk
Post Follow-up to this messageDirk Wolfgang Glomp wrote: I cannot image that IRQs can work while in Unreal mode. > I didnīt know any normal DOS-IRQ that goes to PM, so only memmorymanager do > that? One problem is that the CPU actually switches between RM/PM when CS is reloaded, the trick to set data-segment registers to flat/unlimted, right after b0(CR0) is set, works only until CS become altered. So the final IRET in any IRQ-handler (timer,key,mouse...) will do this unwanted mode transition (turning BigReal/UnReal into PM). Another thing to assume is that RM IRQ-handlers may temporary reload DS/ES/.. and so reset the limit to 64KB again. There are some workarounds for this problems, like what Frank posted, but an easier way is to disable IRQs for short periods or use only FS and GS for flat-addressing, these two are rare used in plain DOS. __ wolfgang
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.