Don't nitpick. When one says "Intel computer" what is meant is "a computer with an Intel x86 or compatible CPU architecture".
Don't nitpick. When one says "Intel computer" what is meant is "a computer with an Intel x86 or compatible CPU architecture".
I actually was using "mov" and not "move". I just made a typo in the code i put on the board, which is never a good thing. The compiler still will not allow me to write to the extended (first word) of the register. I still have no idea how to return the base memory size and extended memory size with the INT 15 function after exploring the ah=0xe820 and ah=0x88 solutions.
For the ax=0x820 solution it is important to be able to write to extended registers because the dx needs to be set to 0x534D4150 ('SMAP').
Any suggestions are appreciated.
Are you required to use the compiler you're using? The age of it may be a factor in it not allowing you to access extended registers(It IS possible to do so in real mode, which is why this is really confusing.). I guess there's not many left for real mode. If you'd be willing to write the whole thing in asm I can really help there, Fasm(flat assembler) make's it really simple to write to any register.
Yes this compiler needs to be used. I would be willing to do it in asm.
Are you sure it won't allow writing to the upper word? What error do you get for:
I'd like to help, it's just that I don't see how it's possible to do what you're asking without writing to extended registers.Code:mov eax,0xe820
This looks promising: Detecting Memory (x86) - OSDev Wiki(int 15, ax=e801) It will probably be more accurate than the one you were using, and it uses the word-sized registers.
Ditto. The NOPs are not needed.WHY!?
If your compiler does not allow you to write to extended registers there are some options. You can prefix the opcode with either 66h? or 67h? if my memory serves me right. This essentially turns mov ax,value into mov eax,value. Once prefix is for string opcodes and one prefix is for register opcodes. They turn 16-bit mov's and registers into 32-bit mov's and registers.
The other option is to use a pure assembly language file and call it from C. The assembler should allow you to access EAX, EBX, etc. If not then get a new assembler or you can use NASM or one of the million x86 assemblers available freely on the internet.
It's 66h. I wish I would've thought of that . Nice catch.
"mov ax,FF00"
"mov eax,FFEE1100"Code:B8 00 FF
So, as you can see, you'll also have to encode backwards the upper word when you mov a value into the extended register.Code:66 B8 00 11 EE FF
today i created a .c file and a separate .asm file containing a function to run the int 15 eax=0xe820. The files link fine, and access to the extended ax register is allowed, but I am going to need to understand how the results will be returned to the C program and printed on the screen.
I am using the following code and it causes the dosbox to hang. i think it has something to do with the line: add di,20
i think it needs to add a dword to the offset, but i don't know how to do this. Any suggestions?
Code:_memmap proc ;push ds ;pop es mov di,500h ;original offset xor ebx,ebx get_e820: mov ebx, 0h ;only first time mov edx, 534D4150h ;'SMAP' mov eax, 0000E820h mov ecx, 20 ;size of in bytes int 15h jc e820_end ;if carry=1 there was an error, jump to end cmp eax,534D4150h jne e820_end ;int 15 should return eax=534d4150, if not jump to end add di,20 ;dword?? add dword di,20 increment offset cmp ebx,0 ;a return value of zero means this is the last descriptor jne get_e820 e820_end: ret _memmap endp
oops i just noticed i need to remove setting ebx = 0!
that solves the hanging problem, but i still need to know how to properly increment 'di'
Last edited by pole1080; 06-17-2010 at 03:18 PM.
First, it's an accepted practice to always increment by 24, even though no one's ever seen an ACPI 3.0 field, it's just easier to keep qword alignment. That means your 20(both the 20 that is passed in ecx and the 20 that is added to di) needs to be a 24, does that answer your question?
Dude, come on! Did you even read the link I gave you? It explains step by step.
If I sound irritated, I'm not, I'm just whinny . I'm glad to help anyone with assembly, it's a dying art.Originally Posted by The link
Note: I just previewed and those big smileys aren't supposed to be there.
Try to run this code and see what happens for you. I don't know where it is storing the memory map at. I need to display the memory map on the screen.
Code:_memmap proc push ds ;push current data segment onto stack pop es ;pop that segment into es for the int 15 mov di, 500h ;original offset mov ebx, 0h ;xor ebx, ebx ;set ebx to zero to start get_e820: mov edx, 534D4150h ;'SMAP' mov eax, 0000E820h mov ecx, 24 ;size of in bytes int 15h jc errora ;if carry=1 there was an error, jump to end cmp eax, 534D4150h jne errorb ;int 15 should return eax=534d4150, if not jump to end add di, 24 ;dword?? add dword di,20 increment offset cmp ebx, 0 ;a return value of zero means this is the last descriptor jne get_e820 errora: mov ah, 2 ; Print a 'A' on the screen mov dl, 'A' ; int 21h ret errorb: mov ah, 2 ; Print a 'B' on the screen mov dl, 'B' ; int 21h ret e820_end: ret _memmap endp
I see one apparent issue, you need to make sure to restore es before you ret. You should also keep a count to return to the calling function. The memmap is stored at the initial value of di. I'm not on a machine with a VM right now, or I'd test it as a boot loader(w/o the int 21s though ).
ok prior to running this function i move ds into ax and print it out on the screen. the value is 5E6C. the offset is initialized to 500, so the memory map should be stored at 5E6C:0C00 right? when i dump the contents of this location it is filled with zeros.
It should start at 5e6c:500h. It's important to note: 5e6c is not constant, it will change depending on where DOS feels like loading you program at.Code:mov di, 500h ;original offset