Author | Message | Time |
---|---|---|
FrostWraith | So I have been studying up on x86 asm lately and have been using Visual Studio to compile it, since I am planning to use both C and asm together. There really is no reason for me doing this other than from a learning perspective. I decided I wanted to make a printf call in asm. I tried my own code and Microsofts example of this and it just will not work. It crashes every time. When i debug, it breaks at the first "pop ebx". If anyone could show me what I am doing wrong, and not telling me to change compilers because this is for school, that would be great! [code]#include <stdio.h> char format[] = "%s %s\n"; char hello[] = "Hello"; char world[] = "world"; int main(void) { __asm { mov eax, offset world push eax mov eax, offset hello push eax mov eax, offset format push eax call printf //clean up the stack so that main can exit cleanly //use the unused register ebx to do the cleanup pop ebx pop ebx pop ebx } }[/code] | January 17, 2008, 5:33 PM |
BreW | What version of visual studio are you using? Are you sure that ebx is unused? Try replacing those last three pops with add esp, 12. | January 17, 2008, 6:12 PM |
FrostWraith | I've tried on both VS 2005 and 2008. Your suggestions doesn't work either. Should I try setting ebx to zero when starting? Heres what I get in debug: [code]First-chance exception at 0x004182bc in test.exe: 0xC0000005: Access violation writing location 0x00001024. Unhandled exception at 0x004182bc in test.exe: 0xC0000005: Access violation writing location 0x00001024.[/code] which naturally is the call to printf [code]__imp__printf: 004182BC adc byte ptr [edx+1023h],bl [/code] | January 17, 2008, 6:13 PM |
UserLoser | pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it [img]http://forums.clubrsx.com/images/smilies/spin.gif[/img] | January 17, 2008, 7:22 PM |
BreW | [quote author=UserLoser link=topic=17275.msg175891#msg175891 date=1200597737] pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it [img]http://forums.clubrsx.com/images/smilies/spin.gif[/img] [/quote] hes cleaning up his stack from the call to printf.. or are you just trying to troll? frostwraith: setting edx to zero isn't going to help a bit, see how it's adding an offset to edx and getting what's at that location? look: [quote] Access violation writing location 0x00001024. [/quote] the call itself looks perfectly fine. And it works perfect for me (I use MSVC6). edx was obviously 1 at the time of calling. That line of code that is right under the label __imp__printf doesn't look quite right, for a few reasons: 1. If it were valid, it should have been push ebp 2. How on earth could a function assume a value already in a register, unless it's __fastcall? And I know it isn't. 3. adc byte ptr [edx + 1023h], bl... that's somewhat random. maybe if it were a mov, and part of a loop, that'd make more sense. but it just isn't. 4. that instruction is exactly 4 bytes long My conclusion: printf is dynamically linked. when you call printf, you're calling that label. it just so happens that there aren't any valid instructions at that label, but instead the address to the real printf. Solution: try call dword ptr [printf] | January 17, 2008, 8:55 PM |
FrostWraith | Thanks a lot! That did the trick. I do understand why that works now, but am unsure why the original code failed. | January 17, 2008, 9:21 PM |
BreW | [quote author=FrostWraith link=topic=17275.msg175893#msg175893 date=1200604874] Thanks a lot! That did the trick. I do understand why that works now, but am unsure why the original code failed. [/quote] Because your linker uses the slower but simpler method of putting printf's address in a call table, and filling in the addresses later. MSVC6 knows exactly where printf is at the time it compiled, so the raw printf call works just fine. Not so with your compiler. | January 17, 2008, 10:09 PM |
FrostWraith | Well you would think that even in Visual Studio 2008 that Microsoft would have been able to think of this. But once again, lets not get into a flame war about MS. | January 17, 2008, 11:50 PM |
Kp | [quote author=brew link=topic=17275.msg175892#msg175892 date=1200603302] [quote author=UserLoser link=topic=17275.msg175891#msg175891 date=1200597737] pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it [/quote] hes cleaning up his stack from the call to printf.. or are you just trying to troll? [/quote] UserLoser was trying to put him on the right track. Do you know what happens when you overwrite ebx in an assembly block? | January 18, 2008, 12:38 AM |
BreW | [quote author=Kp link=topic=17275.msg175898#msg175898 date=1200616706] [quote author=brew link=topic=17275.msg175892#msg175892 date=1200603302] [quote author=UserLoser link=topic=17275.msg175891#msg175891 date=1200597737] pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it [/quote] hes cleaning up his stack from the call to printf.. or are you just trying to troll? [/quote] UserLoser was trying to put him on the right track. Do you know what happens when you overwrite ebx in an assembly block? [/quote] Sure, overwriting ebx is not a very good idea, but IIRC the compiler does save the value of ebx and/or accommodates the rest of the code for its modification across that function. Blame whoever put that assembly on msdn :P | January 18, 2008, 2:26 AM |
UserLoser | [quote author=brew link=topic=17275.msg175892#msg175892 date=1200603302] [quote author=UserLoser link=topic=17275.msg175891#msg175891 date=1200597737] pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it [img]http://forums.clubrsx.com/images/smilies/spin.gif[/img] [/quote] hes cleaning up his stack from the call to printf.. or are you just trying to troll? [/quote] don't reply to my posts, thanks. | January 19, 2008, 7:59 AM |
BreW | [quote author=UserLoser link=topic=17275.msg175906#msg175906 date=1200729570] don't reply to my posts, thanks. [/quote] ha ha ha ha i just replied to your post. again. | January 19, 2008, 1:54 PM |