1. 程式人生 > >C語言與匯編語言相互調用原理以及實例

C語言與匯編語言相互調用原理以及實例

這一 參數表 想要 return urn 類型 ring 符號表 參數

C語言與匯編語言相互調用原理以及實例

1.原理

其實不管是C語言還是匯編語言想要執行都是最終編譯鏈接成為二進制文件。
這裏一定要明確編譯和鏈接是兩個步驟,生成的文件格式也是不一樣的。
編譯生成的文件是一定格式的,裏面包括函數符號表、參數表...等信息,這些信息主要是提供給鏈接階段使用,函數調用是怎麽調用的?是不是指定利用的函數的符號?所以鏈接階段就是將函數調用的符號變成相對地址(要特別註意這個階段,因為這個過程使得C語言和匯編語言相互調用成為可能)

2.下面兩個分別是一個hello.asm(匯編語言文件),main.c(c語言文件)

;hello.asm
extern print_helloworld  
[section .text]  
global print_two_hello_world  
print_two_hello_world:    
call print_helloworld  
call print_helloworld  

/* main.c */
#include "stdio.h"  

extern void print_two_hello_world();  
  
char *strhello = "Hello,world!\n";  
  
void print_helloworld ()  
{  
        printf ("%s",strhello);  
}  
  
int  main ()  
{  
        print_two_hello_world();  
        return 0;  
}  

首先看NASM代碼,先導入一個外部函數print_helloworld(),此函數是C語言定義的一個函數。接下來是定義了一個函數print_two_hello_world,用global關鍵字導出使其可以在C中調用,函數的內容是調用了兩次print_helloword()。
在來看C代碼,代碼很簡單就具體講了,這裏主要數一下我們將主函數放在了C代碼中寫,這時因為我們要使用C代碼的函數庫中的printf()函數,如果C代碼中沒有什麽庫的依賴可以將主函數放在匯編代碼中

3.NASM和C互相調用對方的變量

Nasm代碼

 global string  
extern strhello  
[section .data]  
string:  
    db ‘I am Chinese.‘,0x0A,0x0  
[section .text]  
    global print_hello  
    global cpy_mem  
print_hello:      
    mov edx, 13  
    mov ecx,[strhello]  
    mov ebx,1  
    mov eax,4  
    int 0x80  

C代碼

#include "stdio.h"  
#include "string.h"  
extern char *string;  
extern void print_hello();  
extern cpy_mem (void *dest, int len);  
char *strhello = "Hello,world!\n";  
char *str = NULL;  
int  
main ()  
{  
        printf ("%x\n",&string);  
        str = &string;  
        printf ("%s", str);  
         
        print_hello ();  
        return 0;  
}  

Make後的執行結果如下:
I am Chinese.
Hello,world!
具體的代碼內容就部分析了,這裏主要將兩個關鍵的地方。

1.在C語言中定義了一個strhello的字符串變量,在C語言中strhello表示的是字符串的首地址,比如字符串的地址是0xa00001,而strhello是個指針即4字節其地址為0xb00001, 在C語言中strhello表示的值是 0xa00001 字符串的首地址,但到了NASM中則表示的 strhello變量的首地址了 0xb00001,所以

Nasm代碼

mov ecx,[strhello]  

代碼中加了中括號表示是內容,這一點一定要註意,否則會出錯!!

2.第二點要註意的是,在NASM中定義了一個字符串string , 在C語言中導入的話,就是表示字符串的首地址,因此要引用該字符串一定要取其地址,不要直接轉為(char*)類型直接用,否則出錯,這是因為直接轉的話,就將字符串的前4個字節轉成了字符串指針,但該指針是不確定會出現段錯誤!

C語言與匯編語言相互調用原理以及實例