flat assembler
Message board for the users of flat assembler.

Index > Main > Mixing assembly and C...

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Patrick_



Joined: 11 Mar 2006
Posts: 53
Location: 127.0.0.1
Patrick_ 22 Mar 2008, 00:48
I've always coded in pure assembly, but never combined C + assembly. I'm going to be doing so for a project, so I created a small assembly file...

Code:
format COFF

public foo
foo:
   xor eax, eax
   ret    


Then I linked it with a C source file:

Code:
#include <stdio.h>

extern void foo(void);

int main(void) {

   foo();
   return 0;
}    


But the linker (I'm using gcc/ld) says "undefined reference to 'foo'". What am I doing wrong?

Thanks.
Post 22 Mar 2008, 00:48
View user's profile Send private message Reply with quote
Goplat



Joined: 15 Sep 2006
Posts: 181
Goplat 22 Mar 2008, 01:06
You have to take into account that functions' names get "decorated" by the compiler. For a cdecl function (the default kind in C), this is just an underscore prepended to the name, so a function named "foo" in C source code will be named "_foo" in the object file.

Since fasm does not do name decoration, you have to call the function "_foo".
Post 22 Mar 2008, 01:06
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20522
Location: In your JS exploiting you and your system
revolution 22 Mar 2008, 01:39
You can also use public foo as '_foo'
Post 22 Mar 2008, 01:39
View user's profile Send private message Visit poster's website Reply with quote
Patrick_



Joined: 11 Mar 2006
Posts: 53
Location: 127.0.0.1
Patrick_ 03 Apr 2008, 23:06
Thanks, that worked. I'm having trouble calling libc functions, though. I have something like:

Code:
format MS COFF

extrn printf
public _main

_main:
     ...    


But when I run gcc -o out out.o, it gives me "undefined reference to WinMain@16". I tried "public WinMain@16" and replaced "_main" with "WinMain@16" but no go.

Any ideas? I'm so used to programming in straight assembly...
Post 03 Apr 2008, 23:06
View user's profile Send private message Reply with quote
Patrick_



Joined: 11 Mar 2006
Posts: 53
Location: 127.0.0.1
Patrick_ 03 Apr 2008, 23:26
Oops, nevermind. It seems I was linking against the wrong file when I tried publicizing "WinMain@16". It works now. Very Happy
Post 03 Apr 2008, 23:26
View user's profile Send private message Reply with quote
asmfan



Joined: 11 Aug 2006
Posts: 392
Location: Russian
asmfan 04 Apr 2008, 06:17
Won't create new thread and ask here
What is the difference of
Quote:

format COFF

and
Quote:

format MS COFF

Could someone explain the plain COFF non MS format?
Underscore is for C calling convention. Can fasm automatically decorate names according keywords in proc directives (stdcall/c)?

And more: why cannot I compile this:
Code:
format  MS COFF
INCLUDE 'win32wxp.inc'

public  MyProc

proc    MyProc stdcall uses ebx esi edi, x:DWORD, y:DWORD
local   .cntr:dword
        mov     eax,[x]
        mov     [.cntr],eax
        mov     eax,[y]
        mov     [.cntr],eax
        ret
endp
    

_________________
Any offers?
Post 04 Apr 2008, 06:17
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20522
Location: In your JS exploiting you and your system
revolution 04 Apr 2008, 06:25
asmfan wrote:
Could someone explain the plain COFF non MS format
I don't know this, but have you tried searching yet? Even looking at the source code might give you the answer. Worth a try I suppose.
asmfan wrote:
Can fasm automatically decorate names according keywords in proc directives
No it can't, but perhaps you could write a macro.
asmfan wrote:
why cannot I compile this:
Code:
local   .cntr:DWORD    
The macro only supports UPPERCASE for the DWORD keyword.
Post 04 Apr 2008, 06:25
View user's profile Send private message Visit poster's website Reply with quote
asmfan



Joined: 11 Aug 2006
Posts: 392
Location: Russian
asmfan 04 Apr 2008, 09:37
Once again thank you revolution!
And once again i'm stumbling on lower&upper cases of data reservind/declaration directives aka DD vs. dd, dword vs DWORD, etc... and once again i'm asking Thomasz to make additional aliases to allow this cases...
I know what ms coff is (pecoff_v8.doc helped that) but mere coff... maybe googling will help but if there is a few difference then i thought someone could clarify them here on forum and then Tomasz could kindly put them in fasm.pdf for simplicity of understanding.
Post 04 Apr 2008, 09:37
View user's profile Send private message Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 04 Apr 2008, 09:53
As we talk here about calling Asm code from C, how to do the inverse ?

here's my code :
Code:

;; Asm code
format MS COFF
extrn print
extrn putchar
extrn itoa

print_float:
mov ebp,esp
push dword [esp+4]
call ftol
push eax
mov ebx,eax ; saves eax
push eax
push 10
push 0
push 0
call itoa
push eax
call print
push '.'
call putchar
sub dword [ebp+4], ebx
fld dword [ebp+4]
.loop:
fmul [ten]
fist dword [ebp+12]
push dword [ebp+12]
push 10
push 0
push 0
call itoa
push eax
fisub dword [esp]
call print
push 0
ficom dword [esp]
fstsw [esp]
fwait
pop eax
sahf
jnz .loop
ret 4

---------

/* C code */

#include <stdarg.h>
#define PREFIX 1
#define SUFFIX 0

void clrscr ();
void scroll ();
void print (const char*);
void printf (const char*, ...);
void putchar (char);
extern void print_float (float);
const char* itoa (int,int,int,int); // PS : it's not a standard C compatible itoa Wink
extern void get_vendor (char*);
extern long ftol (float);

unsigned int x=0;
unsigned int y=0;

int kernel_main(void)
{
 char buffer[13];
    clrscr();
   get_vendor(buffer);
        printf("Huhu, Kernel is speaking !");
      printf(">CPU Vendor : %s \n",buffer); // works here
       print_float(28.07103); // but not here, and it reboots
      while(1);
   return(0);
}
    


For the linking, i use :
Code:
fasm float.asm float.o

i586-elf-gcc -ffreestanding -mno-stack-arg-probe -c kernel2.c -o kernel2.o

i586-elf-ld -e kernel_main -Ttext 0x1000 -o kernel2 float.o kernel2.o
i586-elf-objcopy -R .note -R .comment -S -O binary kernel2 kernel2.bin
    


( the i586-elf is for the cross compiler :p )

If i use for example ( extrn "_print" as print ) instead of ( extrn print ), ld give's me the following error message :
Code:
float.o :: undefined reference to '_print'
    


But if i use "extrn print" instead, the linking works without any error message, but Bochs reboots on "call itoa" :s

Who can help me please ?

Thanks Smile
Post 04 Apr 2008, 09:53
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20522
Location: In your JS exploiting you and your system
revolution 04 Apr 2008, 10:02
Whenever you call a c-style function then you must use the c-calling convention whereby you must pop the parameters off the stack after the call.
Code:
...
push dword [ebp+12]
push 10
push 0
push 0
call itoa
add esp,4*4 ;pop off the 4 parameters we pushed up there
...    
Post 04 Apr 2008, 10:02
View user's profile Send private message Visit poster's website Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 04 Apr 2008, 10:48
Thanks, but Bochs still reboots, and in the Bochs console i see : "(invalid) : FFFF" :s
Post 04 Apr 2008, 10:48
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20522
Location: In your JS exploiting you and your system
revolution 04 Apr 2008, 10:57
White-spirit wrote:
Thanks, but Bochs still reboots, and in the Bochs console i see : "(invalid) : FFFF" :s
Remember you have to use the c-call for all c-functions you use, including ftol etc. I only posted an example.
Post 04 Apr 2008, 10:57
View user's profile Send private message Visit poster's website Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 04 Apr 2008, 12:11
Thanks but I prefer do only one C call to see if the issue comes from there :
Code:
push '.'
call putchar
add esp,4
    


It still reboots :s
Post 04 Apr 2008, 12:11
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20522
Location: In your JS exploiting you and your system
revolution 04 Apr 2008, 13:38
I expect you have a stack imbalance. Post your code where you have only the putchar test.
Post 04 Apr 2008, 13:38
View user's profile Send private message Visit poster's website Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 04 Apr 2008, 14:13
Code:
;; ASM Code
format ms coff

extrn putchar
public call_test

call_test:
push '.'
call putchar
add esp,4
ret 4

// C Code
void scroll ();
void putchar (char);
extern void call_test ();

unsigned int x=0;
unsigned int y=0;

int kernel_main(void)
{
    call_test();
        while(1);
   return(0); // not very important
}

void scroll()
{
   int i;
      unsigned char *screen = (unsigned char*) 0xB8000;
   for (i = 0*80; i < 24*80; i++)
   {
              screen[i] = screen[i+160];
  }
      for (i = 24*80; i < 25*80; i++) screen[i] = 0;
    y = 24;
}

void putchar( char s ){
      unsigned char* screen = (unsigned char*) (0xB8000+y*160+x*2);
       if (s == 0xA ){ // LF : 0xA
                x=0;
                y++;
                screen=(unsigned char*) (0xB8000+y*160);
    } else {
          *(screen++)=s;
              *(screen)=0x07;
             x++;
        }
      if (x>=79){
         x=0;
                y++;
        }
      if (y>=24){
         scroll();
           y=1;
        }
}

    


Here's a Bochs screenshot ( notice the '!' after 'Please Visit :' ), and Bochs still reboots Shocked

Image
Post 04 Apr 2008, 14:13
View user's profile Send private message Reply with quote
dap



Joined: 01 Dec 2007
Posts: 61
Location: Belgium
dap 04 Apr 2008, 14:24
Try removing the '4' after 'ret'. Also C functions are public by default, you don't need to use 'extern' in their protoypt. If you want to make them private use the 'static' keyword.
Post 04 Apr 2008, 14:24
View user's profile Send private message Visit poster's website Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 04 Apr 2008, 14:43
I tried, but it's still the same ><
Code:
format ms coff

extrn putchar
public call_test

call_test:
push '.'
call putchar
jmp $ ; To see if it arrives so far
add esp,4
ret
    
Post 04 Apr 2008, 14:43
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 04 Apr 2008, 15:02
a char is a byte.
are you sure you push a dword? is it possible it pushes only a word?

push '.' <-- operand size? word or dword?
Post 04 Apr 2008, 15:02
View user's profile Send private message Visit poster's website Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 04 Apr 2008, 15:43
Thanks edfed, but i don't see any operand size problems, i tested a minimalistic putchar in Asm and it works, so it's a C-call problem :
Code:
format ms coff

public call_test

putchar:
mov al, byte [esp+4]
mov byte [0xB8000], al
mov byte [0xB8001], 0x37
ret 4

call_test:
push '.'
call putchar
jmp $ ; To see if it arrives so far, and yes, it does !
add esp,4
ret
    


Thanks for help .
Post 04 Apr 2008, 15:43
View user's profile Send private message Reply with quote
White-spirit



Joined: 26 Mar 2008
Posts: 27
White-spirit 05 Apr 2008, 15:13
Someone ? :/
Post 05 Apr 2008, 15:13
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.