INT 15 to return memory size

This is a discussion on INT 15 to return memory size within the C Programming forums, part of the General Programming Boards category; Don't nitpick. When one says "Intel computer" what is meant is "a computer with an Intel x86 or compatible CPU ...

  1. #16
    msh
    msh is offline
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Don't nitpick. When one says "Intel computer" what is meant is "a computer with an Intel x86 or compatible CPU architecture".

  2. #17
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    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.

  3. #18
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    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.

  4. #19
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    Yes this compiler needs to be used. I would be willing to do it in asm.

  5. #20
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Are you sure it won't allow writing to the upper word? What error do you get for:
    Code:
    mov eax,0xe820
    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.

    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.

  6. #21
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    WHY!?
    Ditto. The NOPs are not needed.

    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.

  7. #22
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    It's 66h. I wish I would've thought of that . Nice catch.

    "mov ax,FF00"
    Code:
    B8 00 FF
    "mov eax,FFEE1100"
    Code:
    66 B8 00 11 EE 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.

  8. #23
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    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.

  9. #24
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    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

  10. #25
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    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.

  11. #26
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    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.
    Quote Originally Posted by The link
    Basic Usage:
    For the first call to the function, point ESI at the destination buffer for the list. Clear EBX. Set EDX to the magic number 0x534D4150. Set EAX to 0xE820 (note that the upper word of EAX should be set to 0). Set ECX to 24. Do an INT 0x15.

    If the first call to the function is successful, EAX will be set to 0x534D4150, and the Carry flag will be clear. EBX will be set to some non-zero value, which must be preserved for the next call to the function. CL will contain the number of bytes actually stored at ESI (probably 20).

    For the subsequent calls to the function: increment DI by your list entry size, reset EAX to 0xE820, and ECX to 24. When you reach the end of the list, EBX may reset to 0. If you call the function again with EBX = 0, the list will start over. If EBX does not reset to 0, the function will return with Carry set when you try to access the entry after the last valid entry.
    If I sound irritated, I'm not, I'm just whinny . I'm glad to help anyone with assembly, it's a dying art.

    Note: I just previewed and those big smileys aren't supposed to be there.

  12. #27
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    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

  13. #28
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    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 ).

  14. #29
    Registered User
    Join Date
    Jun 2010
    Posts
    23
    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.

  15. #30
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Code:
    		mov 	di, 500h	;original offset
    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.

Page 2 of 4 FirstFirst 1234 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why doesn't this example work for me?
    By xixpsychoxix in forum C++ Programming
    Replies: 4
    Last Post: 03-24-2009, 08:25 PM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Alegro closes out on me
    By campsoup1988 in forum C++ Programming
    Replies: 8
    Last Post: 04-03-2006, 10:40 AM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 09:33 AM
  5. opengl program as win API menu item
    By SAMSAM in forum Game Programming
    Replies: 1
    Last Post: 03-03-2003, 06:48 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21