Hi,
this is my very first post.
Here is my question, hope someone can help.
I have two files, interface.c and interface.asm
interface.c
...
__asm call label_2 // inline assembly : call an assembly label defined in interface.asm
...
interface.asm
...
label_2:
...
I compile interface.asm with GoAsm and interface.c with MinGW, then I link the two object files using the MinGW linker, and it works perfectly, that is label_2 is called correctly. I do not declare label_2 as "extern" in the two files.
The problem arises when I compile interface.asm with GoAsm and interface.c with the microsoft compiler cl.exe .
The cl.exe compiler complains saying ".\interface.c(55) : error C2094: label 'label_2' was undefined"
Now, being aware of name mangling, scope, etc, I tried to prefix underscores, declaring "extern", using the GoAsm switch "/ms", any combination really, but nothing works.
Any ideas? ... thanks
MinGW?
:(
MinGW is the port of the GNU gcc compiler on windows ...
www.mingw.org/ (http://www.mingw.org/)
Hi scalprum.eu
Welcome to the forum.
Have you tried decorating label_2 in the asm file as follows:-
_label_2@0
The number after the @ sign being the number of bytes (in decimal) taken up by the parameters?
Hi jorgon.
.... reading the GoAsm manual, I was aware of the _label_2@0 decoration issue, so I tried, but cl.exe replied the same error code.
I think that cl.exe expects any label to be explicitly declared as global or extern before its use. The problem is that inline assembly does not allow the "extern" keyword.
Moreover, if I declare label_2 as extern in the .c file ...
interface.c
...
extern label_2
...
... cl.exe compiles ok, but then link.exe is unable to match label_2 in the .asm file.
One obvious solution would be to declare label2 as follow:
interface.c
...
extern void __cdecl label_2( ); // let the compiler think label_2 is a C external function
...
label_2(); // call label_2 as a normal C function. Within the interface.asm file there must be a " _label_2: " label.
...
Although this approach may works, it's rather a sort of "hack" that somehow complicates things in frequent use of the "interfacing feature" . The MinGW-gcc compiler does not need this approach.
... does anyone know a simple way of calling/jumping to external labels from C inline assembly ? Thanks ...
I can't find any way to do it without an extern statement, but you can readily call the label from inline assembly. My example complicates the call somewhat, but it could be minimized to simply a call instruction.
code section
_label_2:
mov eax, [esp+4]
add eax, 1
ret
#include <windows.h>
extern cdecl int label_2(int);
int main(void)
{
int x = 12345;
__asm push x
__asm call label_2
__asm mov x, eax
printf("%d\n",x);
getch();
return 0;
}
.... yes, the only way of calling an externally-declared label from C inline assembly, must be of declaring that label as a function first.
Thank you to jorgon and MichaelW for replying!
Here is another example built with Pelles C :
/* Coded with Pelles C 6.00 RC 1 */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern int __stdcall StdOut(char *);
int main(int argc,char *argv[])
{
char *msg="Calling an external label with Pelles C";
__asm{
mov eax,msg
push eax
call StdOut
}
return 0;
}
.code
StdOut FRAME lpszText ; Masm32 function translated to GoAsm
LOCALS hOutPut,bWritten,sl
invoke GetStdHandle,-11
mov [hOutPut], eax
invoke lstrlen,[lpszText]
mov [sl],eax
invoke WriteFile,[hOutPut],[lpszText],[sl],ADDR bWritten,0
mov eax,[bWritten]
ret
ENDF
All the trick is to instruct GoAsm to output decorated symbols :
\GoAsm\GoAsm /ms StdOut.asm
[attachment deleted by admin]
Linking / name decoration is a tricky subject. It's a good thing that we have an expert like Vortex around :bg