linking NASM code with gcc code
linking NASM code with gcc code
if i write a function in NASM, then compile it to object code, how would i call it from my c object code? is there a specific way to write thte function in NASM so that it links with gcc? i hate gcc assembly and want to use NASM for all ym assembly needs
Re:linking NASM code with gcc code
If using c code this:
in your c module:
extern function();
<you can use your function in your code somewhere now>
in your asm module:
; if using windows replace function with _function
global function
function:
<code>
ret
That help?
in your c module:
extern function();
<you can use your function in your code somewhere now>
in your asm module:
; if using windows replace function with _function
global function
function:
<code>
ret
That help?
Re:linking NASM code with gcc code
While that wouls allow you call the functions, as a practical matter, there are a few other issues to be aware of, mostly involving saving registers, and the passing of arguments and return values.
Specifically, gcc requires you to preserve all registers except EAX, EDX, EFLAGS, FS and GS. The stack pointer and base pointer are particularly important to preserve correctly, as they are necessary for restoring the calling function's state. As a general rule, the first thing an assembly function should do when called from C is to push the existing EBP, then copy the current stack pointer to the EBP, so as to set up the stack frame; then any of the other sacred registers which the function used should be pushed as well. For example:
Arguments are passed on the stack, just before the function call is made, in reverse order from how they appear in the C function call. Thus, the call
would push 77 00 00 00, then 17 00 00 00, then the address of the calling function. In case you were puzzled, gcc always uses 32-bit argument size stack segments, and values are pushed in little-endian order. These value are in hex, of course (those who point out that 23dec == 17hex will be assumed to be eligible for immediate ordination as Deacons in the LDD for mentioning it, and referred to in the appropriate manner).
To access the arguments, you need to index them from the EBP, so that to copy the value of bar into EAX, you would use
Finally, return arguments are passed through thr EAX and EDX registers, with arguments larger than 8 bytes passed implicitly by a pointer.
For more details, see the DJGPP FAQ page regarding mixing C and assembly code (it is not specific to DJGPP, however). HTH. CCW.
Specifically, gcc requires you to preserve all registers except EAX, EDX, EFLAGS, FS and GS. The stack pointer and base pointer are particularly important to preserve correctly, as they are necessary for restoring the calling function's state. As a general rule, the first thing an assembly function should do when called from C is to push the existing EBP, then copy the current stack pointer to the EBP, so as to set up the stack frame; then any of the other sacred registers which the function used should be pushed as well. For example:
Code: Select all
global foo
foo:
push EBP
mov EAX, ESP
mov EBP, EAX
push EDI
push ESI
Code: Select all
int foo (int bar, char quux)
foo(23, 'w')
To access the arguments, you need to index them from the EBP, so that to copy the value of bar into EAX, you would use
Code: Select all
mov EAX, [EBP + 8] ; add 4 for the old EBP, and another 4 for the caller's return address
For more details, see the DJGPP FAQ page regarding mixing C and assembly code (it is not specific to DJGPP, however). HTH. CCW.