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

Started by
11 comments, last by SimDemon 20 years, 10 months ago
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
I'll have a link to the TriFaze website as soon as possible. It's still currently being designed, by myself of course! =) I'll update the URL and my signature as soon as possible.Feel free to send me a message on Yahoo! or AOL IM™. =)
Advertisement
push esp
blah
pop esp
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
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.
I'll have a link to the TriFaze website as soon as possible. It's still currently being designed, by myself of course! =) I'll update the URL and my signature as soon as possible.Feel free to send me a message on Yahoo! or AOL IM™. =)
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]
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!!!
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.
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
I'll have a link to the TriFaze website as soon as possible. It's still currently being designed, by myself of course! =) I'll update the URL and my signature as soon as possible.Feel free to send me a message on Yahoo! or AOL IM™. =)
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.
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
I'll have a link to the TriFaze website as soon as possible. It's still currently being designed, by myself of course! =) I'll update the URL and my signature as soon as possible.Feel free to send me a message on Yahoo! or AOL IM™. =)
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

This topic is closed to new replies.

Advertisement