32-bit addr in 16-bit segments - help!!! 
Author Message
 32-bit addr in 16-bit segments - help!!!

I know stuff like this has been discussed recently, but I'm having
trouble getting it to work.

I'm trying to write some assembly code that will do 32-bit
addressing in real mode.  I've downloaded some code from an issue
of DDJ that will enable 32-bit segments.  First of all, will
this work:

                .386P
                .CODE

protsetup       proc    fpointer:fpbyte
                les        bx,fpointer
                lgdt        fword ptr es:[bx]                ; Load GDT

                mov        eax,cr0                                ; Goto prot mode
                or        al,1
                mov        cr0,eax

                mov        es,bx
                mov        fs,bx
                mov        gs,bx                                ; Load gs/es
                and        al,0feh                                ; Go back to real mode
                mov        cr0,eax
                ret
protsetup       endp

where 'fpbyte' is defined as a 'dword'.

Secondly, I'm confused about how the processor knows which size registers
to use.  For instance, the opcode INSD is supposed to read from port
DX and write it to ES:[EDI].  What differentiates that with ES:[DI]?
And what about REP INSB?  Does it decrement CX or ECX?  And how to
make the distinction in MASM 6.0?

The end result is that I want to perform memory-memory and I/O-memory
adressing with XMS without needing to use XMS functions and without
need a real-mode buffer.

Thanx very much!!!!!!!!!  I really need the help on this.  I don't know
of any book that discusses 32-bit stuff in 16-bit segments.



Tue, 22 Aug 1995 05:34:23 GMT  
 32-bit addr in 16-bit segments - help!!!

Quote:
>Secondly, I'm confused about how the processor knows which size registers
>to use.  For instance, the opcode INSD is supposed to read from port
>DX and write it to ES:[EDI].  What differentiates that with ES:[DI]?

The processor uses the maximum size of the segment-selector used by
the instruction. In this case it depends on hos ES is setup.

It is trivial to see wich one is used in protected mode, but in
real-mode it isn't that simple, since the size-attribut depends on the
last load of ES in protected mode. The default is 16-bit, but if you
use the DDJ code ES and FS will have 32-bit attributes. It will
therefore use ES:[EDI]

Quote:
>And what about REP INSB?  Does it decrement CX or ECX?  And how to
>make the distinction in MASM 6.0?

Depends on the segment used (and it may be possible to use prefix to
modify it).

Quote:
>The end result is that I want to perform memory-memory and I/O-memory
>adressing with XMS without needing to use XMS functions and without
>need a real-mode buffer.

Not much idea, since it won't work if you have any kind of
controll-program loaded (such as QEMM, 386^Max etc). Windows in
Enhanced mode (possibly even in Standard mode) have the same effect.


Wed, 23 Aug 1995 05:59:16 GMT  
 32-bit addr in 16-bit segments - help!!!


Quote:
>Secondly, I'm confused about how the processor knows which size registers
>to use.  For instance, the opcode INSD is supposed to read from port
>DX and write it to ES:[EDI].  What differentiates that with ES:[DI]?
>And what about REP INSB?  Does it decrement CX or ECX?  And how to
>make the distinction in MASM 6.0?

spc>   MASM uses the names of the registers.  DX refers to the 16 bit register,
spc> while EDX refers to the 32 bit register.  So,

spc>                 rep     insb
spc>                 rep     insw

spc> uses ES:DI and CX, while

spc>                 rep     insd

spc> will use ES:EDI and ECX.

At least in MASM 5.1, this just isn't true (I don't what MASM 6.0 does).
The operand size of the string instruction in no way correlates to the
address size.  The INSB, INSW, and INSD instructions will all be generated
with no address size override prefix, even regardless of the type of the
segment.  This means that in real mode or a genuine 16-bit protected mode
segment, DI will be used by the CPU, whereas in a genuine 32-bit protected
mode segment, EDI will be used by the CPU.

To cause EDI to be used by the CPU in real mode or a genuine 16-bit
protected mode segment, an address size override prefix of 67h must be
present.  This can be forced out of the assembler by using the more generic
INS instruction, with a typed pointer expression that names EDI as the base
pointer.  For example,

        rep ins  byte ptr [edi],dx

The above would be equivalent to 'rep insb', but would generate a prefix in
a 16-bit segment.  This form requires specification of the DX register.  By
the way, the EDX register could never be used to specify the port address,
since all I/O addresses are limited to 16 bits.

When the CPU uses EDI for a repeated string instruction, ECX is counted
down -- when the CPU uses DI, CX is counted down.  Since CX/ECX counts
iterations, and each iteration will increment/decrement the pointer in
DI/EDI by an amount corresponding to the operand size, it makes more sense
that whether to use CX or ECX should be related to address size.

Gary
--

/  Matsushita Electric Works, Ltd.   UUCP:     uunet!mew.mei.co.jp!gah \
/   13-2, Mita 5-chome, Minato-ku    Fax:      03-3451-0793            \
/    Tokyo 108, JAPAN                Tel:      03-3452-4941            \



Fri, 25 Aug 1995 14:18:38 GMT  
 32-bit addr in 16-bit segments - help!!!

There is no error in the assembler code, but there is no
IDT. I know it, you don't need any one, but if you don't
disable all Interrupts, a crash will follow.

Use it so :

Quote:
>                .386P
>                .CODE

>protsetup       proc    fpointer:fpbyte
>                les         bx,fpointer
>                lgdt                fword ptr es:[bx]       ; Load GDT

;--- Disable all INT'S
**               cli
**               in             al,021h                 ; Save IRQ State
**               mov            dl,al
**               in             0a1h,al
**               mov            dh,al
**               mov            al,0ffh                 ; Disable IRQ's
**               out            021h,al
**               out            0a1h,al

Quote:
>                mov                 eax,cr0                 ; Goto prot mode
>                or          al,1
>                mov         cr0,eax


>             mov            bx,8                    ; prefetch
>                mov         es,bx
>                mov         fs,bx
>                mov         gs,bx                   ; Load gs/es
>                and         al,0feh                 ; Go back to real
> mov                cr0,eax

;--- set back IRQ-Controller ---
**               mov            al,dl
**               out            021h,al
**               mov            al,dh
**               out            0a1h,al
**               sti

Quote:
>                ret

You can also use this code with TASM.
Bye, Sebastian.
+-------------------------------------+-------------------------------
|                                     |                                       |
|  Sebastian Schoenberg               |  Internet:                            |


|                                     |                                       |
+-------------------------------------+---------------------------------------+
Quote:
>protsetup       endp



Fri, 01 Sep 1995 20:03:58 GMT  
 32-bit addr in 16-bit segments - help!!!

Quote:

>>There is no error in the assembler code, but there is no
>>IDT. I know it, you don't need any one, but if you don't
>>disable all Interrupts, a crash will follow.

>>Use it so :

>>>                .386P
>>>                .CODE

>>>protsetup       proc    fpointer:fpbyte
>>>                les         bx,fpointer
>>>                lgdt                fword ptr es:[bx]       ; Load GDT
>>;--- Disable all INT'S
>>**               cli
>>**               in             al,021h                 ; Save IRQ State
>>**               mov            dl,al
>>**               in             0a1h,al
>>**               mov            dh,al
>>**               mov            al,0ffh                 ; Disable IRQ's
>>**               out            021h,al
>>**               out            0a1h,al

[rest of code deleted]

Why bother to mask the 8259A IRQ's?  If you clear the Interrupt Enable bit
of the CPU FLAGS register, there is no chance in the world that a maskable
hardware interrupt will get serviced, much less cause problems with this
particular code.  And if a bug in your code trashed DX before the time to
reenable interrupts, that would be difficult to debug (not that this
version would have that problem, it just doesn't look safe).  Just a CLI
before and an STI sometime after are fine enough.

Of greater concern is NMI, but even this can be disabled in a reasonable
manner on most systems, through the CMOS RAM I/O ports or a dedicated I/O
port.  Also, NMI is usually only generated for memory parity errors and by
break-out switches on hardware-assisted de{*filter*}s.

Gary
--

/  Matsushita Electric Works, Ltd.   UUCP:     uunet!mew.mei.co.jp!gah \
/   13-2, Mita 5-chome, Minato-ku    Fax:      03-3451-0793            \
/    Tokyo 108, JAPAN                Tel:      03-3452-4941            \



Fri, 08 Sep 1995 16:00:13 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. TASM and far jumps from 16-bit segment to 32-bit segment

2. Division 32-Bit/32-Bit with 16-Bit Register

3. 16-bit to 32-bit segments

4. HELP !! converting 16 bit code to 32 bit

5. Help Micro Focus 32 bit calling 16 bit c

6. 16, 16/32, 32 bit Forths: Pros/Cons?

7. 32 bit ST communicating with 16 bit VB

8. How to use SE at any color resolution (256, 16-bit, 32-bit)

9. Can I use 16 bit DLL and 32-bit exe together

10. Changing from 16-bit to 32-bit makes zillion duplicate symbols

11. 16-bit to 32-bit woes

12. Should I use 16 bit or 32 bit??

 

 
Powered by phpBB® Forum Software