Skip to main content
GameDev.net gamedev.net
🔒 Locked

assembly function call

Started by Tera_Dragon Oct 29, 2004 at 5:31 PM 10 replies 1.6k views
Original Post
Tera_Dragon
Tera_Dragon
Before I start I'll just tell you all that I've only really just started using assemly. I am using the following to call the windows MessageBox function in assembly:

push MB_OK
push "Cap"
push "Text"
push NULL
call MessageBox
But it generats a windows error. I think that I've read somewhere that I have the ballance the stack frame once I have called the function. How should I go about this? I do know that I can use invoke with masm instead of call, but I would like to also know how to it this way. Tera_Dragon
____________________________________________________________Programmers Resource Central
doynax
doynax
Why not analyze the assembly source generated by a c compiler?
Any serious compiler has an option to dump the generated assembly code.
Tera_Dragon
Tera_Dragon
I looked at the assembly generated by VC++6.0 and got this (also had some hex numbers at the start of every line, but I think that is just the machine code):
mov         esi,esppush        0push        offset string "Caption" (00426038)push        offset string "Text" (00426030)push        0call        dword ptr [__imp__MessageBoxA@16 (0042c520)]cmp         esi,espcall        __chkesp (00401d40)

I don't really understand this, but I tried it in masm anyway, and it wouldn't build the .obj file.
____________________________________________________________Programmers Resource Central
doynax
doynax
Quote:
Original post by Tera_Dragon
I looked at the assembly generated by VC++6.0 and got this (also had some hex numbers at the start of every line, but I think that is just the machine code):
mov         esi,esppush        0push        offset string "Caption" (00426038)push        offset string "Text" (00426030)push        0call        dword ptr [__imp__MessageBoxA@16 (0042c520)]cmp         esi,espcall        __chkesp (00401d40)

I don't really understand this, but I tried it in masm anyway, and it wouldn't build the .obj file.

The first and two last lines simply checks that the stack pointer is restored, it's only generated in debug mode though.
The function is called through an indirect pointer generated when using dll imports, you'll have to check a win32 asm tutorial for a full explanation.
doynax
doynax
Quote:
Original post by Tera_Dragon
All I really want to know is how I would call the function using call...

Ok, I did some quick googling.. Here's a tutorial that does exactly what you want: http://win32assembly.online.fr/w32_00.txt.
Ladd Spencer
Ladd Spencer

You were right, you DO need to "balance" the stack. As I'm sure you know, you must match each PUSH with a POP and vice versa. As an alternative to calling POP 4 times after your call to MessageBox(), you can simply manipulate the stack pointer manually by adding the number of bytes PUSHed. So your code would look like this:

begin:
PUSH MB_OK //pushed 32 bits
PUSH "Cap" //pushed another 32 bits
PUSH "Text" //etc
PUSH NULL //etc
CALL MessageBox
ADD ESP, 16 //restore stack pointer to value
//it had when we started.

...notice we ADD instead of SUB, the stack grows down. This should work for you, I've had the same problem when I was learning it.
doynax
doynax
Quote:
Original post by Ladd Spencer

You were right, you DO need to "balance" the stack. As I'm sure you know, you must match each PUSH with a POP and vice versa. As an alternative to calling POP 4 times after your call to MessageBox(), you can simply manipulate the stack pointer manually by adding the number of bytes PUSHed. So your code would look like this:

begin:
PUSH MB_OK //pushed 32 bits
PUSH "Cap" //pushed another 32 bits
PUSH "Text" //etc
PUSH NULL //etc
CALL MessageBox
ADD ESP, 16 //restore stack pointer to value
//it had when we started.

...notice we ADD instead of SUB, the stack grows down. This should work for you, I've had the same problem when I was learning it.

It depends on the calling convention. __cdecl requires the caller to restore the stack pointer while with __stdcall it's the responsibility of the callee. Since most win32 functions, including MessageBox, uses the __stdcall convention you shouldn't restore the stack in this case.

Interacting the the operating system in x86 assembly is a mess (without high level constructs like invoke). Personally I try isolate all of my asm code, that way at least it's my own mess..
Tera_Dragon
Tera_Dragon
Quote:
Original post by doynax
Why not analyze the assembly source generated by a c compiler?
Any serious compiler has an option to dump the generated assembly code.


I have VC++6.0 and can only do this in debug mode. Is ther anyway to do it in release mode?
____________________________________________________________Programmers Resource Central
doynax
doynax
Quote:
Original post by Tera_Dragon
Quote:
Original post by doynax
Why not analyze the assembly source generated by a c compiler?
Any serious compiler has an option to dump the generated assembly code.


I have VC++6.0 and can only do this in debug mode. Is ther anyway to do it in release mode?

Shouldn't be any different from debug mode.
Project -> Settings -> Settings For: Release -> C/C++ -> Listing Files -> Assembly with Source Code.
And compile the project in release mode.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.