MemorySize and int 15 / e801 weirdness

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Hadrien
Posts: 9
Joined: Thu Oct 19, 2006 2:30 pm

MemorySize and int 15 / e801 weirdness

Post by Hadrien »

Hi,

Recently I wanted to add some code in my kernel to get the amount of memory installed. My kernel works on PC so I used the Bios int 15. In the future I will deal with the e820 function, but for now I decided to use the e801 function, which looks simpler.

The function works fine when the amount of memory is greater than 16 MiB. But when it is less, I don't get the correct amount. Nowadays most PC have more than 16 MiB so it doesn't really matter for real uses, but just for the sake of curiosity, I wanted to know why the e801 gives so weird results.

I tried my kernel with Virtual PC, using a setting with 4 MiB of RAM. The e801 function reported 3840 KiB of RAM (This counts the first MiB).

I tried the same kind of experiment with VMWare, and 3008 KiB was reported.

I tried with Bochs, and got 4096 KiB (this is what I was expecting from the start).

I didn't try with a real PC because... well, it's quite hard to find a PC with less than 16 MiB nowadays :)

I've been googling like hell to find more information about the e801 function but couldn't find more than small descriptions about parameters and returns.

Do you have any idea why I get results that are less than the installed memory for an amount less than 16 MiB ?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

E801 reports the amount of memory after the 1M mark. Depending on how the emulator works, this can very well be one of 3M, 4M-640k, or 4M.
In this case bochs would always put the given amount of memory past the 1MB mark, and add 640k by default, VMware reports 3MB indicating some memory is overshadowed by the video card and bioses, while MSVPC leaves the A0000-FFFFF hole free of memory so no memory is wasted.

Then there are some specific areas for ACPI and stuff which eat away some memory as well, causing the bios to report less in order to protect these areas.

So to me, the numbers dont sound crazy at all.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Hadrien
Posts: 9
Joined: Thu Oct 19, 2006 2:30 pm

Post by Hadrien »

Thanks Combuster. It looks like I'll be using e820 sooner than expected :|
User avatar
smiddy
Member
Member
Posts: 127
Joined: Sun Oct 24, 2004 11:00 pm
Location: In my cube, like a good leming. ;-)

Post by smiddy »

Hadrien wrote:Thanks Combuster. It looks like I'll be using e820 sooner than expected :|
Here's some code you can use, adjust it to suite your tastes:

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; E820.ASM - Devloped to see what E820 produces.
;;
;; To Assemble: fasm getmem.asm
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    format  MZ                      ; For FASM EXE format
    entry   main:BeginE820          ; Entry is into the main segment, just below

    segment main use16

BeginE820:

    jmp Start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Program data items
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ProgramMessage          db 13,10,'E820 - 1.00.1 Attempt to see E820 information... -smiddy',13,10,13,10,0
RebootMessage           db 13,10,'Press any key to reboot...',13,10,0
NotSupportedMessage     db '<-- CF: Function is not supported (that sucks!).',13,10,0

TheKBytes               db 'K bytes.',0
JustTheBytes            db ' bytes.',0
TheDash                 db ' - ',0
TheSpace                db ' ',0
TheBIOSE820Message      db 'E820: ',0
TheBIOSE820Message1     db 'hSz    Base Address   -  Memory Length    -    Memory Type     - ExtAttr',13,10,0
TheBIOSE820Message2     db ' : ',0
TheHexAfter             db 'h',0

E820Buffer: TIMES 32    db 0
E820BufferLength        equ $ - E820Buffer

TotalMemoryMessage      db '-------------------------------------------------------------------------------',13,10
TotalMemoryMessage2     db '   : Total Memory     : ',0
TotalMemoryMessage3     db '-------------------------------------------------------------------------------',13,10,0

TheHexEndOfLine         db 'h',13,10,0
TheEndOfLine            db 13,10,0
TheBIOSE820MemoryType1  db 'Available to OS    ',0
TheBIOSE820MemoryType2  db 'Reserved Memory    ',0
TheBIOSE820MemoryType3  db 'ACPI Reclaim Memory',0
TheBIOSE820MemoryType4  db 'ACPI NVS Memory    ',0
TheBIOSE820MemoryType5  db 'Unuseable Range    ',0
TheBIOSE820MemoryType6  db 'Undefined Range    ',0

IgnoreRangeMessage      db 'IAR',0
NonVolatileRangeMessage db ' NVR',0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This is the start of the pragram
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Start:

    mov ax,9000h                         ; Set up stack
    mov ss,ax
    mov sp,9500h                         ; Stack pointer setup
    mov ax,cs                            ; Setup the rest of the segment registers
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax
    mov [CodeSegment],ax                 ; Save current codesegment for decisions later

    mov si,ProgramMessage                ; Load program message
    call PrintString                     ; Display welcome message

    call BIOSE820                        ; INT 0x15 AX=0xE820

    cmp [CodeSegment],0202h              ; Compare for booted executeable
    je .Reboot                           ; Yes, go to reboot routine

    mov ax,4C00h                         ; Terminate program if in DOS
    int 21h                              ; DOS interrupt call

.Reboot:

    mov si,RebootMessage                 ; Load reboot message into SI
    call PrintString

    mov ax,0                             ; Load INT 16h get key function
    int 16h                              ; BIOS interrupt call

    db 0EAh                              ; Machine language to jump to
                                         ;    address FFFF:0000 (reboot)

    dw 0
    dw 0FFFFh                            ; No return required
                                         ;    we're rebooting!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Call BIOS INT 15h AX=0E820h
;;
;;    Display memory mapping if available
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BIOSE820:

    pusha

    mov [TotalMemoryInstalled],dword 0      ; Zero out variable
    mov si,TheBIOSE820Message               ; Load entry PrintString
    call PrintString                        ; Display the message
    mov si,TheEndOfLine                     ; Load end of the line
    call PrintString                        ; Display the message
    
    mov di,E820Buffer                       ; Load buffer into DI (uses ES:DI)
    xor ebx,ebx                             ; INT 0x15 AX=0xE820 continuation value
    mov edx,0534D4150h                      ; Place "SMAP" into EDX
    mov ecx,E820BufferLength                ; Save buffer size into ECX
    mov eax,0E820h                          ; Load EAX with E820h
    int 15h                                 ; Call BIOS interrupt

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; CF on first call to INT 0x15 AX=0E820h is an error
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    jc .NotSupported                        ; On error jump to the not supported section

    mov si,TheBIOSE820Message1              ; Load the setup string
    call PrintString                        ; Print the string

.BIOSE820_1:

    cmp eax,0534D4150h                      ; Compare EAX with "SMAP"
    stc                                     ; Set the carry flag
    jne .BIOSE820_4                         ; If it isn't SMAP finish off look at E820

    push ebx                                ; Save EBX
    push ecx                                ; Save ECX

    mov eax,ecx                             ; Place ECX into EAX to display
    mov cl,8                                ; Choose 8 bits to display
    call ToHex                              ; Turn binary into hex ASCII
    mov si,HexBuffer                        ; Load hex buffer
    call PrintString                        ; Print hex buffer (size of the record; all have been 14h)
    
    mov si,TheBIOSE820Message2              ; Load the start of the record in tabular form
    call PrintString                        ; Print the start

    mov eax,[di + 4]                        ; Load EAX with BaseAddrHigh
    mov CL,20h                              ; Choose 32 bits
    call ToHex      
    mov si,HexBuffer
    call PrintString
    mov eax,[di + 0]                        ; Load EAX with BaseAddrLow
    mov CL,20h
    call ToHex
    mov si,HexBuffer
    call PrintString

    mov si,TheDash
    call PrintString

    mov eax,[di + 12]                       ; Load EAX with LengthHigh
    mov CL,20h
    call ToHex
    mov si,HexBuffer
    call PrintString
    mov eax,[di + 8]                        ; Load EAX with LengthLow
    mov CL,20h
    call ToHex
    mov si,HexBuffer
    call PrintString

    mov si,TheHexAfter
    call PrintString

    mov si,TheDash
    call PrintString

    mov si,TheSpace
    call PrintString

;     mov eax,dword [di + 16]                   ; Load memory type into EAX
;     mov CL,8                              ; Only show the last 8 bits
;     call ToHex
;     mov si,HexBuffer
;     call PrintString

    mov si,TheBIOSE820MemoryType1
    mov eax,dword [di + 16]
    cmp eax,1
    jg .NotTheOS
    mov eax,[di + 8]                        ; Save low length for now (needs to include high later)
    add eax,[TotalMemoryInstalled]          ; Add already saved amount in variable
    mov [TotalMemoryInstalled],eax          ; Save variable
    mov si,TheBIOSE820MemoryType1
    jmp .DoPrintString

.NotTheOS:

    cmp eax,2
    jg .NotReserved
    mov si,TheBIOSE820MemoryType2
    jmp .DoPrintString

.NotReserved:

    cmp eax,3
    jg .NotReclaim
    mov si,TheBIOSE820MemoryType3
    jmp .DoPrintString

.NotReclaim:

    cmp eax,4
    jg .DoACPINVS
    mov si,TheBIOSE820MemoryType4
    jmp .DoPrintString

.DoACPINVS:

    cmp eax,5
    jg .DoPrintString
    mov si,TheBIOSE820MemoryType5    

.DoPrintString:

    call PrintString

.BIOSE820_2:

    pop ecx
    cmp ecx,24                              ; Is the record 24 bytes long
    jne .EndLine
    test dword [di + 20],1                              ; Check for Ignore Address Range
    je .IgnoreRange
    jmp .CheckNonVolatile
    
.IgnoreRange:

    mov si,IgnoreRangeMessage
    call PrintString
    
.CheckNonVolatile:

    test dword [di + 20],1 shl 1                        ; Check for non volatile RAM
    jne .EndLine
    
    mov si,NonVolatileRangeMessage
    call PrintString
    
.EndLine:   

    mov si,TheEndOfLine
    call PrintString

    pop ebx
    or ebx,ebx
    je .BIOSE820_3

    mov edx,0534D4150h                      ; "SMAP"
    mov ecx,E820BufferLength
    mov eax,0E820h
    int 15h

    jnc .BIOSE820_1                         ; No CF then continue looking at map

.BIOSE820_3:

    clc

.BIOSE820_4:

    mov si,TotalMemoryMessage
    call PrintString
    mov eax,[TotalMemoryInstalled]
    mov cl,20h
    call ToHex
    mov edi,HexBuffer
    mov eax,16
    call AddForwardSpaces
    mov si,HexBuffer
    call PrintString
    mov si,TheHexAfter
    call PrintString
    mov si,TheDash
    call PrintString
    mov eax,[TotalMemoryInstalled]
    call ToDecimal
    call AddCommas
    mov edi,CommaBuffer

    mov eax,14                              ; String of 14, to compare
    call AddForwardSpaces
    
    mov si,CommaBuffer
    call PrintString
    mov si,JustTheBytes
    call PrintString
    mov si,TheEndOfLine
    call PrintString
    
    mov si,TotalMemoryMessage3
    call PrintString
    jmp .DoneE820

.NotSupported:

    mov si,NotSupportedMessage
    call PrintString
    mov si,TheEndOfLine
    call PrintString
    
.DoneE820:
    
    popa

    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Dumps DS:SI to the screen using video BIOS call or DOS call
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PrintString:

    pusha
    
.DoItAgain:

    lodsb                          ; Load byte at DS:SI into AL
    or al,al                       ; Test if character is 0
                                   ;    (end of string)
    jz .Done                       ; Go to Done if Zero

    cmp [CodeSegment],0202h        ; Did we boot this puppy?
    jne .DOS                       ; No, then do DOS routine

    ;;;;;;;;;;;;;;;;;;;;;;;
    ;; BIOS Print Character 
    ;;;;;;;;;;;;;;;;;;;;;;;

.BIOS:

    mov ah,0Eh                     ; Put character on screen at the
                                   ;    currrent cursor location
    mov bx,7                       ; Video attribute for the character
    int 10h                        ; Call BIOS

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; DOS Print Character (added to use pipes)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.DOS:

    mov dl,al                      ; Put character into DL
    mov ah,2                       ; Output Character (Interrupt 21h, service 2)
    int 21h
    
    jmp .DoItAgain

.Done:

    popa
    
    ret                            ; Return to caller

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; ToHex
;; Loads HexBuffer with ASCII corresponding to 8, 16, or 32 bit interger in hex.
;; Requires interger in AL, AX, or EAX depending on bit size
;; Requires the number of bits in the CL
;; Returns a full buffer or an empty buffer on error
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ToHex:

    pusha

    MOV BX,0                                ; Load BX with pointer offset
    MOV edx,EAX                             ; Save the EAX to EDX
    CMP CL,8                                ; Check for 8 bits
    JNE .Check16
    JMP .ConverterLoop                      ; Start loading the buffer

.Check16:

    CMP CL,10h                              ; Check for 16 bits
    JNE .Check32
    JMP .ConverterLoop                      ; Start loading the buffer

.Check32:

    CMP CL,20h                              ; Check for 32 bits
    JNE .ErrorBits

.ConverterLoop:

    MOV EAX,edx                             ; Reload EAX with the converter
    SUB CL,4                                ; Lower bit count by 4 bits
    SHR EAX,CL

    AND AL,0Fh
    ADD AL,'0'
    CMP AL,'9'
    JBE .LoadBuffer
    ADD AL,'A'-'0'-10                       ; Convert to "A" to "F"

.LoadBuffer:

    MOV [HexBuffer + BX],AL                 ; Load buffer with AL
    INC BX                                  ; Increment buffer pointer
    CMP CL,0                                ; Check if we're done
    JNE .ConverterLoop                              ; Do next byte

.ErrorBits:

    MOV byte [HexBuffer + BX],0             ; End the string with a zero
    
    popa

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; ToDecimal - converts whatever is in EAX to ASCII string, places it in a buffer
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DivisorTable    dd 1000000000,100000000,10000000,1000000,100000,10000,1000,100,10

ToDecimal:

    pusha

    mov byte [ZeroNotLoaded],0              ; Initialize variable
    mov word [DivisorNumber],0              ; Initialize variable
    MOV BX,0                                ; Start BX at zero

.LoopToDecimal:

    mov EDX,0
    push eax
    movzx eax,word [DivisorNumber]
    mov ecx,4
    mul ecx
    push bx
    mov bx,ax
    mov ECX,DWORD [DivisorTable + bx]
    pop bx
    pop eax
    DIV ECX
    inc word [DivisorNumber]
    cmp al,0
    je .CheckZeroNotLoaded
    
.ReturnToLoop:

    ADD AL,48                               ; Update to an ASCII character representation
    MOV [DecimalBuffer + BX],AL             ; Load decimal buffer
    mov byte [ZeroNotLoaded],1              ; Gone through the loop at least once, show it
    INC BX                                  ; Increment the BX
    cmp ecx,dword [DivisorTable + (8 * 4)]  ; Was that the last divisor?
    je .MoveOut                             ; Yep, do the one's column. :D
    mov EAX,EDX                             ; Put remainder in EAX
    jmp .LoopToDecimal
    
.CheckZeroNotLoaded:

    cmp byte [ZeroNotLoaded],1
    je .ReturnToLoop
    mov eax,edx
    jmp .LoopToDecimal
    
.MoveOut:

    mov EAX,EDX                             ; Put remainder in EAX
    ADD AL,48                               ; Update to an ASCII character representation
    MOV [DecimalBuffer + BX],AL             ; Load decimal buffer
    INC BX                                  ; Increment the BX
    MOV DL,0
    MOV [DecimalBuffer + BX],DL             ; Load decimal buffer with ending zero

    popa

    RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; StringLength:
;;
;;  Assumes string start at ES:EDI
;;
;;  Returns the string length in the ECX
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

StringLength:

    push edi
    push eax

    sub ecx,ecx
    sub al,al
    not ecx
    cld
    repne scasb
    not ecx
    dec ecx

    pop eax
    pop edi

    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; AddCommas:
;;
;;  Assumes string start at DS:ESI
;;
;;  Populates CommasBuffer with at most three extra commas
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

AddCommas:

    push eax
    push ebx
    push ecx
    push edx

    mov ecx,0                       ; Set ECX to 0
    mov edi,DecimalBuffer           ; Place a pointer to DecimalBuffer in EDI
    call StringLength               ; Get the string length of DecimalBuffer

    cmp ecx,4
    jb .ZeroCommas
    cmp ecx,7
    jb .OneComma
    cmp ecx,10
    jb .TwoCommas
    jmp .ThreeCommas

.ZeroCommas:

    mov eax,0
    jmp .GoOn

.OneComma:

    mov eax,1
    jmp .GoOn

.TwoCommas:

    mov eax,2
    jmp .GoOn

.ThreeCommas:

    mov eax,3

.GoOn:

    dec ecx                         ; Go to last character

    mov [CommasNeeded],eax          ; Save the number of need commas
    mov ebx,eax                     ; Save EAX to EBX
    add ebx,ecx                     ; Increase number for string (to new last character location)
    mov al,0                        ; Put 0 in AL for null termination on string
    mov [CommaBuffer + ebx + 1],al  ; End string with null from AL
    mov edx,0                       ; zero out EDX for placing commas

.Loop:

    cmp edx,3                       ; If so, add a comma
    je .AddComma
    cmp edx,6                       ; If so, add a comma
    je .AddComma
    cmp edx,9                       ; If so, add a comma
    je .AddComma
    jmp .NormalExchange

.AddComma:

    mov [CommaBuffer + ebx],byte ','
    dec ebx

.NormalExchange:

    mov AL,byte [DecimalBuffer + ecx] ; Get character from ECX location in DecimalBuffer
    mov [CommaBuffer + ebx],AL      ; Put character into CommaBuffer
    cmp ecx,0                       ; Are we done?
    je .Done                        ; Yes, goto done
    dec ecx                         ; Subtract 1 from ECX to point to next needed character
    dec ebx                         ; Decriment 1 from EBX into new CommaBuffer
    inc edx                         ; Add number of characters moved
    jmp .Loop                       ; Do it again

.Done:

    pop edx
    pop ecx
    pop ebx
    pop eax

    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; AddForwardSpaces: 
;;
;;  Assumes string start at ES:EDI, total length in EAX
;;
;;  Prints forward spaces to the screen given total length in EAX
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

AddForwardSpaces:

    push edi
    push esi
    push eax
    push ecx
    
    call StringLength
    cmp eax,ecx
    jbe .Done                   ; If less or equal than total length, nothing to do.
    
.MainLoop:

    mov si,TheSpace
    call PrintString
    
    inc ecx
    cmp eax,ecx
    ja .MainLoop
    
.Done:

    pop ecx
    pop eax
    pop esi
    pop edi
    
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Uninitiated variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CodeSegment             rw 1        ; Saves the codesegment for decisions
TotalMemoryInstalled    rd 1        ; Saves the total useable memory of the system
HexBuffer               rb 18       ; Sixteen bytes with the ending zero
DecimalBuffer           rb 12       ; Eleven bytes with the ending zero
CommaBuffer             rb 15       ; Fourteen bytes for DecimalBuffer information
CommasNeeded            rd 1        ; Saving commas needed
TheRemainder            rd 1        ; Saving the Remainder
TheResult               rd 1        ; Saving the Result
OrderOfTens             rd 1        ; Saving order of tens (10^n)
ZeroNotLoaded           rb 1        ; Used for checking zero starting numbers
DivisorNumber           rw 1        ; Used to keep track of division

E820MemoryMapBuffer     rb 10240    ; Should be enough for entire map, more can be added later
User avatar
Hadrien
Posts: 9
Joined: Thu Oct 19, 2006 2:30 pm

Post by Hadrien »

I have things to read. Thanks smiddy :wink:
Post Reply