News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Memory Map

Started by zak100, February 19, 2010, 06:21:07 PM

Previous topic - Next topic

zak100

Hi,
I have got a code related to memory map. I have not understood everything of this code. But thing which hindering me is that its using 32 bit registers. Should I have to switch to protected mode?


; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
; inputs: es:di -> destination buffer for 24 byte entries
; outputs: bp = entry count, trashes all registers except esi
do_e820:
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc short .failed ; carry set on first call means "unsupported function"
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne short .failed
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je short .failed
jmp short .jmpin
.e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc short .e820f ; carry set means "end of list already reached"
mov edx, 0x0534D4150 ; repair potentially trashed register
.jmpin:
jcxz .skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short .notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je short .skipent
.notext:
mov ecx, [es:di + 8] ; get lower dword of memory region length
test ecx, ecx ; is the qword == 0?
jne short .goodent
mov ecx, [es:di + 12] ; get upper dword of memory region length
jecxz .skipent ; if length qword is 0, skip entry
.goodent:
inc bp ; got a good entry: ++count, move to next storage spot
add di, 24
.skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short .e820lp
.e820f:
mov [mmap_ent], bp ; store the entry count
ret ; test opcode cleared carry flag
.failed:
stc ; "function unsupported" error exit
ret






Zulfi.

dedndave

no - in fact, i don't think it will work in protected mode
from what i understand, to use 32-bit registers in real mode, all you should need is....

        .386

(or higher) after the model directive

redskull

Remember that when running anything this low-level within a DOS Box under Windows NT, always take the output with a grain of salt.  I'm fairly certain NTVDM doesn't support this particular INT 15 call, so ensure you run this in 'real' real mode

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

FORTRANS

Hi,

   As Dave says you can use 32 bit instructions in real mode.
You have to make sure that the assembler knows to be in 16-bit
mode or the default instruction mode will be incorrect.  I Think
Dave and MichaelW have posted posted code that shows how
to do this.

   When you are in protected mode interrupts work differently
than when in real mode.  If that has not been set up correctly,
it will not work.  Also BIOS code is 16-bit and a lot of examples
of setting up protected mode also set up the 32-bit execution
mode.

Regards,

Steve N.

dedndave

i think he is reading Ralf
if i recall, it was E820h where Ralf said some BIOS's expect the high word of eax to be 0

zak100

Hi,
I got it from OSDev Wiki & topic is "Detecting Memory (x86)". There is no author name.

mov [mmap_ent], bp   ; store the entry count


Should I declare the mmap_ent as:

mmap_ent db  0

How can I use it for indirect addressing ?

Zulfi.



dedndave

those guys over there use NASM, mostly
for MASM, you can use

        mov     mmap_ent,bp   ; store the entry count

but, BP is a word register, so mmap_ent should be a word

mmap_ent dw ?

zak100

Thanks for removing this confusion. I really appreciate your replies. Its very good forum. Replies come immediately.

Zulfi.

zak100

Hi,
Can somebody plz guide me with this statement:

mov [es:di + 20], dword 1


I am getting following error:
sect8_2.asm(277) : error A2032: invalid use of register

Zulfi.

dedndave

try this

        mov dword ptr es:[di+20],1

not sure if that will work in 16-bit mode - if not, you'll have to split it up

        mov word ptr es:[di+20],1
        mov word ptr es:[di+22],0

zak100

Hi,

Thanks. In this code they have not specified the declaration for the buffer of the list pointed by ES:DI. Should I declare it as:

buffer db ?

and then point ES:DI towards it using following code:

       
push es
        push cs
        pop es
        mov di, offset buffer+LoadOfs

     



What is the function of bp?



xor bp, bp ; keep an entry count in bp




I cant understand this entry count?

I want to first print this qword Base address. The loop counter should be set to 64??

Kindly somebody guide me with this.

Zulfi.

FORTRANS

Hi,

Quote
What is the function of bp?

Code:

xor bp, bp ; keep an entry count in bp

I cant understand this entry count?

   A call to Int 15H Fn E820 returns information about a memory
block.  You supply a buffer for the BIOS to fill with this information.
This code snippet calls this an "entry".  BP is a count of the memory
blocks in that computer.  You call the BIOS Int 15H more than once
to get a map of the memory.

Regards,

Steve

dedndave

the buffer needs to be large enough to hold all the entries
the problem is, you do not know how many entries there will be on any given computer - lol
but, you are in luck   :bg
you are only interested in the last entry
if i remember, it is 20 bytes per entry
just use the same 20 bytes over and over
when the function tells you there are no more entries, you will have the one you want in the buffer

zak100

Hi,

Thanks for the reply.

Quote

BP is a count of the memory
blocks in that computer.

But these blocks can be of different sizes (qword or dword) and some of them can be filled and some are unused???

Should I declare the buffer as 'qword'? I want to do it in steps. First I want to print the Base address which is of 'qword' size.

Zulfi.

dedndave

you could define a structure
have a look at Steve's memory map code to see how it is done (i think he did it that way   :P )

something like this...

MMap_Descriptor STRUCT
  BaseAddress_Lo dd ?
  BaseAddress_Hi dd ?
  ByteLength_Lo  dd ?
  ByteLength_Hi  dd ?
  RangeType      dd ?
MMap_Descriptor ENDS

now, MMap_Descriptor is a new data type

MMap_Table MMAP_Descriptor <>

now, you have a structure named MMap_Table of the type MMap_Descriptor
you can access one of the elements like this

        mov     eax,MMap_Table.ByteLength_Lo