From: Luke D. <cod...@ho...> - 2004-04-29 04:41:56
|
Good example, but wouldn't it be better to change this: >result: > push eax ; display the output > push dword mesg2 > call _printf > add esp, 4 > > pop eax ; restore eax - the highest value is the return value To this: result: push eax ; save eax push eax ; printf second arg push dword mesg2 ; printf first arg call _printf add esp, 8 ; remove two args pop eax ; restore eax ...like the first call to printf? In practice it works your way but I think that relies on a function not changing its own arguments. I have also attached the GNU as equivalent of your code, which has fairly minor changes and may be built using: gcc -c testobj.c gcc -c objtest.s gcc objtest.o testobj.o -o test Luke >From: "Stephen Ray" <st...@mr...> >Reply-To: min...@li... >To: <min...@li...> >Subject: [Mingw-users] Re: [Mingw-users][OT] linking c or c++ with asm >object file >Date: Wed, 28 Apr 2004 23:27:41 -0300 > >Here are some links I found Googling: > >http://www.unixwiz.net/techtips/win32-callconv.html - Windows specific >information >http://www.cs.umbc.edu/~chang/cs313.s02/stack.shtml - information for >Linux, >but much is still applicable > >Simply put, you push parameters onto the stack, from right to left. So, >calling printf("the first is %d, the second is %d", a, b) you would first >push b, then a, then the address of the string. This leaves the first >parameter on the top of the stack, the second just below, and so on. Return >values are usually passed in eax. I seem to recall 64 bit values being >returned in the pair eax/edx (maybe I have it backwards - some >experimentation should be done). In your routine, you have to preserve some >registers (I think they are edi, esi, ebx, and ebp, and you have to have >esp >pointing to the return value when you call ret). Other C routines will >preserve the same registers. I could be wrong here as well, but this is >what >I have. >When you've called the routine, and it's returned, remove the arguments you >passed to it from the stack. You put them there, you take them off. Other >calling conventions have the callee remove them. > >You didn't specify an assembler. I'm hoping you didn't mean gas. Anyway, >here's a simple example using nasm for windows and gcc. >In windows, at least, it seems you have to add an underscore to the >beginning of the name of anything you want to access from outside the file. >In C, you call compare(a, b), but in the assembly file it's defined as >_compare, and when using functions from the C library, you have to add the >underscore to their names as well. >The C program passes two numbers to the assembly routine. The assembly >routine takes those two arguments, outputs them (in order) and compares the >two, outputting the larger. The assembly routine uses the C library routine >printf(). >The c code was compiled using: > gcc -c testobj.c > nasmw -f win32 objtest.asm -o objtest.o > gcc objtest.o testobj.o -o test > >Here's the C program: > >int main(){ > int a = 32; > int b = 55; > compare(a, b); > return 0; >} > >Here's the assembly routine: > >; objtest.asm >; >; compare: takes two integer arguments, displaying the >; arguments and which is the greater. Returns >; the greatest value. >; >; C-style signature: int compare(int a, int b); >; > >[SECTION .text] > >extern _printf >global _compare > >_compare: > push ebp ; set up stack frame > mov ebp, esp > push ebx ; must preserve ebp, ebx, esi and edi > push esi ; we are free to modify other registers, so > push edi ; are any other c routines we call. > > mov eax, [ebp + 8] ; move a into eax > mov ebx, [ebp + 12] ; move b into ebx > > push eax ; save a on the stack before calling printf > > push ebx ; set up the stack for call to printf > ; printf("The parameters were %d and %d, ", a, b) > push eax > push dword mesg1 > call _printf > > add esp, 12 ; remove the parameters from the stack > pop eax ; restore a - printf put it's return value there > > cmp eax, ebx > jge result > xchg eax, ebx > >result: > push eax ; display the output > push dword mesg2 > call _printf > add esp, 4 > > pop eax ; restore eax - the highest value is the return value > > pop edi ; restore the registers we saved then return > pop esi > pop ebx > mov esp, ebp ; destroy the stack frame > pop ebp > ret > >[Section .data] > mesg1 db "The parameters were %d and %d, ", 0 > mesg2 db "and the largest was %d", 13, 10, 0 > >Hope this helps > >Stephen > >----- Original Message ----- >From: "Justinas" <jug...@uo...> >To: <min...@li...> >Sent: Wednesday, April 28, 2004 5:03 PM >Subject: [Mingw-users] linking c or c++ with asm object file > > > > Hi there. > > Does anybody tryed to link c or c++ .o file with compiled > > object written in assembly language, or can provide some > > useful links on that topic? I'm interested in structure of > > asm PROCedure, how are values passed (i know that is ower > > stack, but what's the order and so on), returning value. I'm > > talking about intel's x386 architecture. > > > > Thanks in advance! > > _________________________________________________________________ Protect your inbox from harmful viruses with new ninemsn Premium. Go to http://ninemsn.com.au/premium/landing.asp?banner=emailtag&referrer=hotmail |