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

Thanks. I never worked on structures in Assembly language but your example shows that its not difficult.
I cant understand following fields:

ByteLength_Lo  dd ?
  ByteLength_Hi  dd ?
  RangeType      dd ?


BaseAddress is clear to me.

Zulfi.

zak100

Hi,

According to that Article :
Quoteincrement DI by your list entry size:
       
The structure which you told me is of 80 bytes. Should I increase DI by 80 bytes for next call?

Should I have one more dd field in the structure for ACPI 3.0 Extended Attributes bitfield??


From this structure it seems that each time I invoke int 15h I would get a base address of a region.

Kindly somebody guide me with this.

Zulfi.

FORTRANS

#17
Hi,

QuoteI cant understand following fields:

ByteLength_Lo  dd ?


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


   This corresponds to the description in the article.

Quote
   * First qword = Base address
   * Second qword = Length of "region" (if this value is 0, ignore the entry)
   * Next dword = Region "type"
         o Type 1: Usable (normal) RAM
         o Type 2: Reserved - unusable
         o Type 3: ACPI reclaimable memory
         o Type 4: ACPI NVS memory
         o Type 5: Area containing bad memory
   * Next dword = ACPI 3.0 Extended Attributes bitfield (if 24 bytes are
           returned, instead of 20)

   So if I rearrange things a bit, it becomes:


MMap_Descriptor STRUCT
  BaseAddress   DQ      ?       ; * First qword = Base address
  ByteLength    DQ      ?       ; * Second qword = Length of "region"
  RangeType     DD      ?       ; * Next dword = Region "type"
  ACPI_Attrib   DD      ?       ; * Next dword = ACPI 3.0 Extended Attri
MMap_Descriptor ENDS


   (I added a record for the attributes like you mentioned.)
So Dave showed you the structure using DWORD sized fields,
which is a bit easier when programming 32-bit code.

Quote
The structure which you told me is of 80 bytes. Should I increase DI by 80 bytes for next call?

   Actually what Dave showed you was 20 bytes, five
DWORDS.  The one I just showed was 24 bytes.  So
you would declare multiple structures and increment for
each new call, or reuse the first one each time.


Call15_1        MMap_Descriptor <>      ; Set DI to point to the first one, and
Call15_2        MMap_Descriptor <>      ; increment by 24  to point to second.
Call15_3        MMap_Descriptor <>
Call15_4        MMap_Descriptor <>
Call15_5        MMap_Descriptor <>


HTH,

Steve N.

zak100

Thanks. Very good explanations by you people. Will these five variables be enough to check the entire memory or I may need more?

Zulfi.

FORTRANS

Hi,

   Different computers will have different numbers of blocks.
In the other thread with MichaelW's software, the examples
posted showed two with six blocks and one with four.  And
there should be another to show the end block.   Five was
just an example showing the allocation of structures.  They
are not all that big, so starting with ten or sixteen won't hurt
much.  MichaelW seems to reuse just one in a loop.  (If I
read his program correctly.)

Regards,

Steve

zak100

Very Good. I must do some programming now. And inform you people about the results.

Zulfi.

zak100

Hi,
I want to print this base address once its stored in the structure i.e I want to print the following field:

BaseAddress   DQ      ?


Can somebody guide me in this regard?

Zulfi.

zak100

Hi,
I am putting my code for memory map but still I dont have any clue to display the base address:


do_e820_Step1:
        push es
        push cs
        pop es
        mov di, offset call15_1+LoadOfs
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx,0534D4150h ; Place "SMAP" into edx
mov eax, 0e820h
mov dword ptr es:[di + 20],  1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 15h
jc short failed         ; carry set on first call means "unsupported function"
mov edx, 0534D4150h ; 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
jmpin:
jcxz skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short skipent
test byte ptr es:[di + 20], 1 ; if so: is the "ignore this data" bit clear?
je short skipent

skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short e820f
        mov ah,0
        mov end_of_list, ah
e820f:
mov mmap_ent, bp ; store the entry count
        pop es
ret
failed:
stc ; "function unsupported" error exit
ret





displayBaseAddress:
                   
                    ret

Can somebody help me with displaying the base address??

Zulfi.



dedndave

#23
Zulfi
this routine will convert it to a zero-terminated ASCII string
use the display routine we have used before to display it

;-----------------------------------------------------------------------

Qw2Hex  PROC    NEAR

;convert a QWORD from a memory location to ASCIIZ hexidecimal string

;Call With: DS:SI = address of binary QWORD input value
;           DS:DI = address of 17-byte ASCII buffer

        push    ax
        push    cx
        push    si
        push    di
        mov     cx,8
        add     si,7

Qw2Hx0: mov     al,[si]
        dec     si
        mov     ah,al
        shr     al,1
        shr     al,1
        shr     al,1
        shr     al,1
        cmp     al,0Ah
        sbb     al,69h
        das
        mov     [di],al
        inc     di
        mov     al,ah
        and     al,0Fh
        cmp     al,0Ah
        sbb     al,69h
        das
        mov     [di],al
        inc     di
        dec     cx
        jnz     Qw2Hx0

        mov     [di],cl
        pop     di
        pop     si
        pop     cx
        pop     ax
        ret

Qw2Hex  ENDP

;-----------------------------------------------------------------------

EDIT - fixed a typo

        jnz     Qw2Hx0

zak100

Thanks . I would try this.

Zulfi.

dedndave

this version is probably better, Zulfi
it can be used for smaller integers, as well
you have to tell it how many binary bytes to convert in CX

        mov     si,offset BinaryValue
        mov     di,offset AsciiBuffer
        mov     cx,sizeof BinaryValue
        call    MB2Hex


;-------------------------------------------------------------------------------

MB2Hex  PROC    NEAR

;convert a multi-byte binary from a memory location to ASCIIZ hexidecimal string

;Call With: DS:SI = address of binary input value
;           DS:DI = address of ASCII buffer (minimum length = 2 x CX + 1)
;              CX = number of binary input bytes to convert

        push    ax
        push    cx
        push    di
        add     si,cx

MB2Hx0: dec     si
        mov     al,[si]
        mov     ah,al
        shr     al,1
        shr     al,1
        shr     al,1
        shr     al,1
        cmp     al,0Ah
        sbb     al,69h
        das
        mov     [di],al
        inc     di
        mov     al,ah
        and     al,0Fh
        cmp     al,0Ah
        sbb     al,69h
        das
        mov     [di],al
        inc     di
        dec     cx
        jnz     MB2Hx0

        mov     [di],cl
        pop     di
        pop     cx
        pop     ax
        ret

MB2Hex  ENDP

;-------------------------------------------------------------------------------

FORTRANS

#26
Hi,

   Cough.  Dave beat me to it.  Twice.  Oh well, here is my
version anyway.  Why waste typing effort?

Regards,

Steve


; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;    Call with DS:SI pointing to a QWORD (eight bytes) to be
; displayed as hexadecimal.
QW2Hex$:
        PUSH    SI      ; Save registers used by routine.
        PUSH    AX
        PUSH    CX

        STD             ; String instructions decrement.

        ADD     SI,7    ; Point to last byte, (Intel big end).
        MOV     CX,8    ; Number of bytes to print.
QW_1:
        LODSB           ; Get a byte.
        CALL TOASCII    ; Display as hex.
        LOOP    QW_1

        CLD             ; Restore default.

        POP     CX
        POP     AX
        POP     SI

        RET

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;    This routine converts the one byte binary number in the
; AL register into its hexadecimal ASCII representation and
; prints these two bytes to the standard output or console.
; 4 March 2010,
;   Changed TOASCII routine to use AAM varient instead of MOV,
; AND, and SHR codes on nybbles.

TOASCII:
        PUSH    AX      ; Make safer for debugging.
        PUSH    DX

        XOR     AH,AH   ; Clear AH for AAM using base 16.
DB      0D4H, 10H       ; Isolates high nybble in AH and low
                        ; nybble in AL.
        PUSH    AX      ; Save low nybble.
        MOV     AL,AH   ; And process high digit first.

        CMP     AL,10   ; Convert to ASCII hex using "magic".
        SBB     AL,69H
        DAS

        MOV     DL,AL
        CALL ConOutByte ; DOS Fn 2 or BIOS 10H Fn 0EH (or whatever).

        POP     AX      ; Retrieve low digit in AL.

        CMP     AL,10   ; Convert to ASCII hex.
        SBB     AL,69H
        DAS

        MOV     DL,AL
        CALL ConOutByte

        POP     DX
        POP     AX

        RET

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

zak100

Hi,

Fine. I actually tried Dave's work last night but it didnt work. I would try your's now.Its very good to get these 2 different versions. I would try to understand them as its difficult to understand Assembly programs without the help of an alg.


Zulfi.

dedndave

the first one had a typo in it, Zulfi - i fixed it
here is a little demo program using the multi-byte version...

zak100

Hi Steve,

Quote

Call with DS:SI pointing to a QWORD (eight bytes) to be
; displayed as hexadecimal.



Thanks for your code. I have one prob. which is stated in the comment. In my code, ES:DI points to the QWORD which is natural after executing 15h. This comment means I cant use your code.

Hi Dave,
Thanks for your help. I was able to compile your program. I would check your updated version some time maybe tomorrow.

I appreciate your consistent help in solving my problems.

Zulfi.