Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

SimDemon

ASM Problem ("Saving" ESP register problems) (Please help...)

This topic is 5528 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey there. I''m programming a game with my DirectX 3D engine, and I want to optimize it using ASM (Assembly Language). Right now I am trying to call the IDirect3DDevice8::SetRenderState() functions ASM. Here is my code right now:
  
		__asm 
		{
			;; Enable z-buffer parameters
			PUSH 1                              ;; Second parameter
			PUSH D3DRS_ZENABLE                  ;; First parameter

			;; Call the IDirect3DDevice8::SetRenderState function
			MOV  EAX, DWORD PTR g_pDevice       ;; Interface of d3d device
			MOV  ECX, DWORD PTR [EAX]           ;; Move EAX pointer to ECX
			MOV  EDX, DWORD PTR g_pDevice       ;; Set EDX as ''g_pDevice''
			PUSH EDX                            ;; Push out EDX

			CALL DWORD PTR [ECX+200]            ;; Set the z-buffer render state
		}
  
When I run the executable file it gives me an error. It says that the ESP register was saved correctly. I have tried "ADD ESP, (4, 8, 16, 32, and 64)", and they still give me an error. Here is the code that I converted, using Listing Files in the Settings:
  
	mov	eax, DWORD PTR ?g_pDevice@@3PAUIDirect3DDevice8@@A ; g_pDevice
; Line 434
	mov	ecx, DWORD PTR [eax]
; Line 435
	mov	edx, DWORD PTR ?g_pDevice@@3PAUIDirect3DDevice8@@A ; g_pDevice
; Line 436
	push	edx
; Line 438
	call	DWORD PTR [ecx+200]
; Line 440
	add	esp, esi
  
and I have also tried the "ADD ESP, ESI", but sometimes my computer will freeze and I have to restart it. Can someone please give me the correct method for "saving" the ESP register? Thanks in advance! =) If thispost = 0 Then GoBack() Else Read() End If

Share this post


Link to post
Share on other sites
Advertisement
I just tried that, but it gives me the same error. It says ESP wasn''t saved properly across a function call. Also, it says it may be caused by calling a function declared with one calling convention with a function pointer declared with a different calling convention.

Share this post


Link to post
Share on other sites
quote:
Original post by SimDemon
PUSH 1
PUSH D3DRS_ZENABLE
PUSH EDX

When I run the executable file it gives me an error. It says that the ESP register was saved correctly. I have tried "ADD ESP, (4, 8, 16, 32, and 64)", and they still give me an error.


I'd be inclined to think you'd have to 'add ESP, 12', as you're pushing 3 DWORDs.


[edited by - Namethatnobodyelsetook on May 27, 2003 12:20:16 AM]

Share this post


Link to post
Share on other sites
Try a stack frame....


--------------------------------------------------
push ebp ; preserve base pointer
mov ebp, esp ; stack pointer into ebp

; write you own code here.

mov esp, ebp ; restore stack pointer
pop ebp ; restore base pointer

ret
----------------------------------------------------

push esp
blah
pop esp

will not work is esp is modified, because you lost the address where you pushed esp!!!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Why? calling SetRenderState using assembly will be no faster than using C++. Before you start assembly optimizing, take a look at the output assembly of your C++ compiler. If it''s horribly inefficient (usually not) it might be worth it for functions that are called very often.

Share this post


Link to post
Share on other sites
None of those suggestions work either. I am calling more than on SetRenderState() function. No matter what I do it won''t work. I don''t know what is wrong with this. =(

If thispost = 0 Then
GoBack()

Else
Read()
End If

Share this post


Link to post
Share on other sites
there is no reason to do this:

MOV EAX, DWORD PTR g_pDevice ;; Interface of d3d deviceOV
MOV ECX, DWORD PTR [EAX] ;; Move EAX pointer to ECX

it is the same as:

MOV ECX, DWORD PTR [g_pDevice] ;; Move value at pointer to ECX

the only reason to stuff like this usually is to get to a pointer to a pointer. this is what you may want:

MOV EAX, DWORD PTR [g_pDevice] ;; pointer to d3d interface
MOV ECX, DWORD PTR [EAX] ;; Move EAX pointer to ECX

I know how to do this with assem, but I''m currently reinstalling my comp. Thats my best guess atm.

Share this post


Link to post
Share on other sites
I am never going to figure this out. I tried what you suggested, and it gives me the same error. It''s an access violation. When I try to debug, it comes up with disassembly, and just says this:

int 3

If thispost = 0 Then
GoBack()

Else
Read()
End If

Share this post


Link to post
Share on other sites
WHY DO YOU NEED ASM TO MAKE A FUNCTION CALL???

The problem is the calling convention (cdecl) requires the callER to fix ESP. simply subtract from ESP the number of bytes you pushed onto the stack for the paramiters. Check other listings for how this works. I strongly suggest you use C++ for this, there is no benifit of using ASM other then if you are processing huge amounts of data. Even then C++ can be optimized sufficiently

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!