Page 1 of 2
Incorrect RAM count with INT 15h
Posted: Wed Aug 03, 2005 1:55 pm
by Kemp
I am using int 15h to get a quick count of memory as noted in the osfaq, but it doesn't appear to be giving me correct results. Attached is the current output I obtain, which shows there being 300 (hex) KB of memory available. This is 768KB (plus the 1MB that it ignores), whereas I have Bochs set up to use 32MB. Has anyone else had any problems with this? This function can only return an available amount up to about 64MB but as Bochs is set to 32MB I wouldn't see that being a problem. No doubt there will be something stupid wrong with my code, but there honestly isn't very much to it, appropriate excerpts:
Code: Select all
; Attempt to count up system memory
MOV AH, 88h
INT 15h
MOV RAMCount, AX
MOV SI, OFFSET RAMCount
MOV DI, OFFSET RAMOut
CALL bin2hex
MOV SI, OFFSET msgRAMCount
CALL ShowMsg
MOV SI, OFFSET RAMOut
CALL ShowMsg
and
Code: Select all
bin2hex:
LODSB
MOV AH, AL
AND AX, 0000111111110000b
SHR AL, 4
ADD AX, 3030h
STOSB
LODSB
MOV AH, AL
AND AX, 0000111111110000b
SHR AL, 4
ADD AX, 3030h
STOSB
RETN
(my usual bin2hex routine, anything over 9 gets symbols rather than letters but that isn't occurring here)
Code: Select all
msgRAMCount DB 'Current system RAM: ', 00h
RAMCount DW 0000
RAMOut DB '0000h KB after 1Mb', 0Dh, 0Ah, 00h
Re:Incorrect RAM count with INT 15h
Posted: Wed Aug 03, 2005 6:44 pm
by smiddy
Hi Kemp,
I have written some routines for determining RAM sizes. As you have experienced, not every way to do it is exact. Meaning some way work and others do not, but not on the same machine, as the one's that didn't work before work on another, but the one's that did don't. If that makes sense. I am off to bed now, so I will have to give you screen shot for now of where I am with the project (memory determination; research for my OS):
Code: Select all
GETMEM - 0.17.021E Attempt to see what memory is installed... -smiddy
BIOS:
15h:
E820: Base Address - Memory Length - Type
: 0000000000000000 - 000000000009FC00h - 01 << Available to OS >>
: 000000000009FC00 - 0000000000000400h - 02 << Reserved Memory >>
: 00000000000F0000 - 0000000000010000h - 02 << Reserved Memory >>
: 0000000000100000 - 0000000027EF0000h - 01 << Available to OS >>
: 0000000027FF0000 - 0000000000008000h - 03 << ACPI Reclaim Memory >>
: 0000000027FF8000 - 0000000000008000h - 04 << ACPI NVS Memory >>
: 00000000FEC00000 - 0000000000001000h - 02 << Reserved Memory >>
: 00000000FEE00000 - 0000000000001000h - 02 << Reserved Memory >>
: 00000000FFF80000 - 0000000000080000h - 02 << Reserved Memory >>
----------------------------------------------------------------
: Total Memory : 27F8FC00h - 670,628,864 bytes.
----------------------------------------------------------------
12h:
: Lower Memory : 0009FC00h - 654,336 bytes.
15h:
E801:
: Extended Memory : 27EF0000h - 669,974,528 bytes.
----------------------------------------------------------------
: Total Memory : 27F8FC00h - 670,628,864 bytes.
----------------------------------------------------------------
12h:
: Lower Memory : 0009FC00h - 654,336 bytes.
15h:
88 :
: Extended Memory : 03FFFC00h - 67,107,840 bytes.
----------------------------------------------------------------
: Total Memory : 0409F800h - 67,762,176 bytes.
----------------------------------------------------------------
CMOS:
: Lower Memory : 000A0000h - 655,360 bytes.
: Extended Memory : 03FFFC00h - 67,107,840 bytes.
----------------------------------------------------------------
: Total Memory : 0409FC00h - 67,763,200 bytes.
----------------------------------------------------------------
PROBE:
: Extended Memory : 27F00000h - 670,040,064 bytes.
----------------------------------------------------------------
: Total Memory : 27F9FC00h - 670,694,400 bytes.
----------------------------------------------------------------
PnP BIOS : Base Address - Memory Length - Type
: 00000000 - 0009FC00h - 13 << Available to OS >>
: 0009FC00 - 00000400h - 10 << Read Only Memory >>
: 000F0000 - 00010000h - 10 << Read Only Memory >>
: 00100000 - 27EF0000h - 13 << Available to OS >>
: 27FF0000 - 00008000h - 10 << Read Only Memory >>
: 27FF8000 - 00008000h - 10 << Read Only Memory >>
: FEC00000 - 00001000h - 10 << Read Only Memory >>
: FEE00000 - 00001000h - 10 << Read Only Memory >>
: FFF80000 - 00080000h - 10 << Read Only Memory >>
----------------------------------------------------------------
: Total Memory : 20h - 670,628,864 bytes.
This should make you salivate a bit. There is a posting on BOS where I uploaded the EXE which you can run in Windows, though it doesn't do all the BIOS stuff. It is best to run it in good old DOS:
http://bos.asmhackers.net/forum/viewtopic.php?id=64
Enjoy!
Re:Incorrect RAM count with INT 15h
Posted: Wed Aug 03, 2005 6:50 pm
by QuiTeVexat
I think bin2hex is your problem.
For one, it appears you only stosb twice, meaning only two bytes will ever be outputted by bin2hex. For a 16-bit bin2hex conversion, two bytes need to go in, and four need to come out. If you replace stosb with stosw, you'll find that it outputs the right digits, but in the wrong order.
And as you noted, adding 30h won't give you the correct digit if it is above 9. So when you output, you need to check if the digit is above 9, and, if so, add ('A' - 10). And because of this, you need to do loop thru and do each digit individually. So your MOV-AND-SHR-ADD thing isn't going to work for you.
I would rewrite the routine entirely.
I would also like to mention that whenever I've used ah=88h int=15h for memory sizing, my computer with 512MB of RAM would return only 15MB anyway.
Re:Incorrect RAM count with INT 15h
Posted: Wed Aug 03, 2005 7:17 pm
by AR
88h is an old function, I updated the Wiki with a newer function that provides more information.
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 1:54 am
by Kemp
@Smiddy:
That's a rather convoluted listing
I see that your int 15h function 88h is giving you the right value (well... the maximum value it can do).
@QuiTeVexat:
One STOSB for two bytes... ::) Told you there would be some stupid mistake in there. As for the letters being done wrong, this isn't a production function by any stretch of the imagination, I can cope with symbols for now, and it'll be rewritten once I have a couple more bits sorted out.
Edit:
Tested it properly and it now gives me 15Mb as the result, as with you. Time to use a more comprehensive function I think. It's annoying that I now get the values with the first two digits last and vice veras, I also don't see why it should happen. It reads a byte from Address, writes a word to Address2, reads a byte from Address+1, writes a word to Address2+2, how can that go backwards?
Edit2:
No, I see it *slaps head* fool
@AR:
I check that out
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 3:07 am
by Kemp
Actually no, the more I think about it the less I get why it flips the first and second pairs. Flipping the digits within a pair I can understand, but not the pairs themselves. Demo run:
1) Load 100 in SI
2) Load 200 in DI
3) Call bin2hex
4) Loads a byte from SI (100) and increments
5) Does its thing
6) Stores a word at DI (200) and increments (by 2)
7) Loads a byte from SI (101) and increments
8 ) Does its thing
9) Stores a word at DI (202) and increments (by 2)
10) Returns
It's just the same code twice, the second run doesn't know there has already been a run through. So how does the second word end up before the first one?
Edit:
Modified the bin2hex so it can do a number of any length and tried it with 01234567h, which ended up as '67452301'. I'm thoroughly confused as to how that can go backwards.
And suddenly it hits me... ::) ::) ;D I was thinking in terms of the number I was typing, whereas in the hex dump it's
6745 2301
The whole byte swapping thing really does my head in when I'm not expecting it >:(
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 3:20 am
by Solar
Have you cleared the direction flag?
Anyway:
...doesn't work for digits >9, since 'A' is 0x41, not 0x3A...
I used an algorithm that processes individual digits (i.e., 4-bit nibbles), masking them to lowest 4 bit and using that value as offset into a "0123456789ABCDEF" string. I admit that it doesn't do any little-endian turning-around at all and prints stuff in big-endian order, but that's what I prefer anyway. Perhaps it gives you an idea. (And I hope I didn't screw up in translating it from AT&T to Intel and adjusting it to your SI / DI needs.
)
Code: Select all
_bin2hex:
MOV AX, [SI]
MOV SI, hexdigits
MOV CX, 0x4
_bin2hex_loop:
ROL AX, 0x4
MOV BX, AX
AND BX, BYTE +0x0f
MOV BX, [BX+SI]
MOV [DI], BX
INC DI
DEC CX
JNZ _bin2hex_loop
hexdigits db '0123456789ABCDEF'
I'm not sure what ndisasm means with the '+' in front of "0x0f", but I'm sure you do.
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 3:23 am
by Kemp
I think I'll switch to something like your lookup table, that's the only clean way I can see to get the letters. In fact, I did implement a lookup table version in my first-stage, but it ended up taking up a bit too much of my little amount of spare space, so I fell back on the symbols version.
I can never tell when the bytes being backwards and stuff is going to be a problem, I just have to try it and see what happens, it's a bit of a blind-spot for me.
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 3:26 am
by Solar
To make the above print values "Intel-correctly" (ugh
):
Code: Select all
_bin2hex:
MOV AX, [SI]
MOV SI, hexdigits
MOV CX, 0x4
MOV DX, 0x1
_bin2hex_loop:
ROR AX, DX
MOV BX, AX
AND BX, BYTE +0x0f
MOV BX, [BX+SI]
MOV [DI], BX
INC DI
DEC CX
MOV DX, 0x3
JNZ _bin2hex_loop
hexdigits db '0123456789ABCDEF'
(1 roll-right for first digit, 3 roll-rights on the others.)
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 3:33 am
by Solar
Kemp wrote:
I think I'll switch to something like your lookup table, that's the only clean way I can see to get the letters.
Well, you
can do:
Code: Select all
cmp al, 0x3a
jl xxx;
add al, 0x07
xxx:
cmp ah, 0x3a
jl yyy;
add ah, 0x07
But that still leaves you with the NUXI problem you have, and rapidly eats up the space you saved by not using the lookup.
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 3:53 am
by Kemp
Weel, I figure I can modify my current code slightly and get something like:
Code: Select all
bin2hex:
LODSB
MOV AH, AL
AND AX, 0000111111110000b
SHR AL, 4
MOV BX, OFFSET hexTable
MOV AL, [BX + AL]
MOV AH, [BX + AH]
STOSW
LOOP bin2hex
RETN
hexTable DB '0123456789ABCDEF'
(written on-the-fly, so it might be a bit broken)
All I need to do now is fix the whole backwards thing, which I have a plan for.
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 5:08 am
by Solar
Kemp wrote:
All I need to do now is fix the whole backwards thing, which I have a plan for.
You are aware that your binary constant is of word length, and thus most likely interpreted as low-byte, high-byte as well?
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 5:34 am
by Kemp
This works, don't start making me doubt it even more
each pair of characters that this creates are in the right order (ie, a single run through will give the correct result). I see what you're saying, but I don't mind how the 0000111111110000 is stored in memory as I never write it to or read it from there, it's just applied to the contents of the register.
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 5:41 am
by Solar
Just thinking that you might be masking the wrong nibbles... I'd need pen and paper to really figure out what you're doing, and Intel
data notation already gives me a headache without worrying about
NASM notation...
Re:Incorrect RAM count with INT 15h
Posted: Thu Aug 04, 2005 5:47 am
by Kemp
It is backwards, but it cancels out the number being read in backwards (if my working out is correct). Also, I'm using TASM, just for extra syntax differences ;D