39: Mixed programming of C language and assembly language

Table of Contents

Compilation process

Compilation tips

How are functions called in C language?

Register pushing process

C language function calling process

function calling process

function return process

Calling convention in C language

Stack frame layout used by gcc compiler

ebp is the core register for function calls and function returns

Writing Linux applications in assembly language

interactive keywords

Notes on mixed assembly and C programming

summary

think


Compilation process

Compilation knowledge

How are functions called in C language?

Register Pushing Process

Calling function func pushes the function’s return address onto the stack. At this time, the esp stack pointer register will move down.

When the program executes ret, the program returns to the original location where call was called. At the assembly code level, what call does is exactly the opposite of what ret does.

C language function calling process

Function calling process

Function return process

Calling Convention in C Language

Stack frame layout used by gcc compiler

ebp is the core register for function calls and function returns

Writing Linux applications in assembly language

global_start

[section .data]
    vstr db "D.T.Software",0X0A

[section .text]
_start:
    mov edx,13
    mov ecx,vstr
    mov ebx,1
    mov eax,4
    int 0x80
    
    mov ebx,0
    mov eax,1
    int 0x80

Compile and link, run as follows:

delphi@delphi-vm:~$ nasm -f elf entry.asm -o entry.o
delphi@delphi-vm:~$ ld -s entry.o -o app.out
delphi@delphi-vm:~$ ./app.out
D.T.Software
delphi@delphi-vm:~$ 

Interactive keyword

  1. global : Export symbols (variables or functions) from assembly language
  2. extern: use symbols (variables or functions) defined in external files

Case Analysis:

Let’s look at the next demo:

entry.asm

global_start
globalvstr
globalvlen
global print

extern c_func;

[section .data]
    vstr db "D.T.Software",0X0A
    vlen dd $-vstr

[section .text]
_start:
    mov ebp,0
    
    call c_func
    
    call exit
    
print:
    push ebp
    mov ebp,esp
    
    mov edx,[ebp + 12]
    mov ecx,[ebp + 8]
    mov ebx,1
    mov eax,4
    int 0x80
    
    
    pop ebp
    ret
    
exit:
    mov ebx,0
    mov eax,1
    int 0x80
    

main.c


extern void print(char*,int len);
extern char vstr[];
extern int vlen;

int c_func()
{
    print(vstr,vlen);
    return 0;
}

Compile, link, run:

delphi@delphi-vm:~$ nasm -f elf entry.asm -o entry.o
delphi@delphi-vm:~$ gcc -c main.c -o main.o
delphi@delphi-vm:~$ ld -s entry.o main.o -o app.out
delphi@delphi-vm:~$ ./app.out
D.T.Software
delphi@delphi-vm:~$

Next, change main.c to the following program:


extern void print(char*,int len);
extern char vstr[];
extern int vlen;

int c_func()
{
    char* delphi = "Delphi\\
";
    
    //print(vstr,vlen);
    
    print(delphi,7);
    
    return 0;
}

Now you just need to compile the c file, then link and run:

delphi@delphi-vm:~$ gcc -c main.c -o main.o
delphi@delphi-vm:~$ ld -s entry.o main.o -o app.out
delphi@delphi-vm:~$ ./app.out
Delphi
delphi@delphi-vm:~$

Precautions for mixed assembly and C programming

  1. The same target file format (such as: elf format)
  2. The same function calling convention (such as: cdecl calling convention)
  3. The same activity record (stack frame) structure (eg: ebp benchmark)

Summary

Thinking

Can you change the c_func function name in the main.c file to the main function name?

Of course not, the compilation can pass, but linking errors will occur.

delphi@delphi-vm:~$ nasm -f elf entry.asm -o entry.o
delphi@delphi-vm:~$ gcc -c main.c -o main.o
delphi@delphi-vm:~$ ld -s entry.o main.o -o app.out
entry.o: In function `_start':
entry.asm:(.text + 0x6): undefined reference to `c_func'