Click to See Complete Forum and Search --> : Creating a Memory Manager in Assembly?


David2010
November 24th, 2010, 10:53 PM
This one has puzzled me for a couple days now.

I need a way to detect how much RAM is being used.

I have an address range of:

0x00000500 to 0x00007BFF
0x00007E00 to 0x0007FFFF
0x00080000 to 0x0009FBFF

I tried this:



proberam:
wbinvd
mov di, [0x00000500]
mov si, 0
mov ax, 0
cmp di, ax
je .empty ;Jump if ax is null
mov si, di ;Else put value in si

ret

.empty:
mov si, 0
ret



To find out if there was any data in 0x00000500 and it results as 0.

I am not sure how to write data directly into a memory address. If I could do this then it would make testing a great deal easier.

Is there anything really obvious that I am doing wrong?

Also how would I increment a memory address to test a range of addresses?

I thought about doing this:



add di, 0x00000100



However I don't think that would provide the desired results.

David2010
November 25th, 2010, 10:04 AM
This allows me to write data to an address:



proberam:
wbinvd
mov ax, 50000
mov [0x00000600], ax
mov bx, [0x00000600]
mov si, 0
mov ax, 0
cmp bx, ax
je .empty ;Jump if ax is null
mov si, bx ;Else put value in si

ret

.empty:
mov si, 0
ret




However when reading the address it only gives me the returned value. Not the size of it.

How do I find the size of a value located in an address in RAM.

Eri523
November 25th, 2010, 02:22 PM
I'm not sure I really understand what you are trying to do there.

Trying to write to a memory location and then checking whether you can read back the written value actually is a way of checking whether there is RAM at that memory location. (But maybe you should also check whether your test value incidentally already was stored at that location before your write.) But then you still wouldn't know whether it's general-purpose RAM or some kind of memory-mapped I/O space like, e.g., video RAM.

Also, of course you only can check it that way if you are sure the address range you are testing doesn't contain live data (including your own code!), because that would get overwritten by the test. So you should save the original value at the address in question and finally write it back after the test in case there's a chance that it currently is in use. It also would be a good idea to disable interrupts at least as long as your test pattern is stored in memory, because otherwise an interrupt routine might accidentally try to use the data at that location which then would be invalid.

And I suppose a test like that would only be guaranteed to return meaningful results on an actual hardware-based real-mode system. I'm not sure that it even would work in the Windows DOS box.

The address ranges you present in your OP could well be 20-bit linear addresses of a real-mode system, which would also match the 16-bit code you show. But be aware that of course you can't squeeze a 20-bit address into a 16-bit register. You would have to use the segmented real-mode addressing scheme instead.

However when reading the address it only gives me the returned value. Not the size of it.

Yes, naturally. How should a single RAM memory cell know the size of the RAM it is located in? ;) Of course you have to calculate the size yourself from the range on valid addresses you detect. (Well, on an actual real-mode system the calculation wouldn't really be that hard, as you can alwys assume RAM to start at 0000:0000. It wouldn't even work without that, because this is the mandatory location of the real-mode interrupt vector table.)

HTH

Eri523
November 25th, 2010, 04:44 PM
... and, of course, a standard PC BIOS will return the amount of available "conventional memory" in kB in AX in respense to a call to INT 12H (http://www.ctyme.com/intr/rb-0598.htm). Nowadays it is most likely that it will return 640 kB. And as this memory is all you can access from real mode without doing any twists, it is likely to be sufficient for simple cases.