1. 程式人生 > >C語言調用匯編和彙編呼叫C語言

C語言調用匯編和彙編呼叫C語言

1.C語言調用匯編

程式的入口是main,在main裡調用匯編的函式。

在C語言中,要extern 一個函式宣告即可,然後這個函式在彙編裡面實現。

在彙編裡面,用EXPORT 把C語言定義的函式名引進來,再開始編寫函式名開始的段

#include<stdio.h>
extern int sum(int a,int b,int c,int d,int e,int f);
int main(){
    int result = sum(1,2,3,4,5,6);  
    return 0; 
}
彙編程式碼可新建一個sum.asm檔案,在工程中新增這個檔案即可。        
        AREA    EXAMPLE,CODE,READONLY
        EXPORT    sum
        ENTRY
        
sum
        ADD R0,R0,R1
        ADD R2,R2,R3
        ADD R0,R0,R2
        
        LDR    R4,[SP]
        LDR R5,[SP,#4]
        
        ADD R4,R4,R5
        ADD R0,R4,R0
        
        BX LR
        
        END
函式傳參:

4個以內的引數,直接存放在R0~R3 這4個暫存器裡面。

4個以後的引數放在堆疊裡。

如果函式有返回值,那麼返回值放在R0裡。

Debug看看編譯器是怎麼處理的,我們就怎樣把引數取出來。

還是比較易懂

首先是

R0 =6   R1=5   R2=4   R3=3

然後把R1的值放在堆疊裡,R13=5,然後R1=2

然後吧R0的值放在堆疊的下一個位置,R13+4=6,然後R0=1.

之後就是:

R0=1,R1=2,R2=3,R3=4

堆疊裡面:

所以取引數的時候就是:

LDR    R4,[SP];R4=5
LDR R5,[SP,#4];R5=6

把相加的結果放在R0,然後BX LR返回

可以看到:

可以驗證的確R0是存放返回值的。


例子:

;C語言中extern void macRM68090_WR_CMD(int cmd);  R0 為cmd
    AREA    EXAMPLE,CODE,READONLY
    EXPORT    macRM68090_WR_CMD
    ENTRY
        
macRM68090_WR_CMD
	;macRM68090_RS_CLR;macRM68090_CS_CLR 
	LDR R1, =0x30 
	ldr r4, =0x40010C14 
	STR R1, [r4]            ; GPIOB->BRR = 0x10; GPIOB->BRR = 0x20;  
	          	
	;macRM68090_8BIT_DATAOUT(cmd&0xFF00); 
	AND R1, R0, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0X00FF
	ORR R2, R1, R3
	ldr r4, =0x40010C0C 
	STR R2, [r4]
	
	;macRM68090_WR_CLR;macRM68090_WR_SET 
	LDR R1, =0x08
	ldr r4, =0x40010C14 
	STR R1, [r4]             ;GPIOB->BRR = 0x08;
    ldr r4, =0x40010C10 	
	STR R1, [r4]            ;GPIOB->BSRR = 0x08;  
	
	;macRM68090_8BIT_DATAOUT(((cmd<<8)&0xFF00));
	MOV R2, R0, LSL#8
	AND R2, R2, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0x00FF
	ORR R2, R0, R3
    ldr r4, =0x40010C0C 
	STR R2, [r4] 
	
	;macRM68090_WR_CLR ; 
	ldr r4, =0x40010C14 
	STR R1, [r4]  ; GPIOB->BRR = 0x08;   
	
	;macRM68090_WR_SET ;macRM68090_CS_SET
	LDR R1, =0x28  
	ldr r4, =0x40010C10 
	STR R1, [r4]  ; GPIOB->BSRR = 0x08; GPIOB->BSRR = 0x20; 
	
    BX LR
    NOP	
	END

;C語言中extern void macRM68090_WR_DATA(int data);  R0 為data
    AREA    EXAMPLE,CODE,READONLY
    EXPORT    macRM68090_WR_DATA
    ENTRY
	
macRM68090_WR_DATA
	;macRM68090_RS_SET
	LDR R1, =0x10  
	ldr r4, =0x40010C10 
	STR R1, [r4]   ; GPIOB->BSRR = 0x10;
	
	;macRM68090_CS_CLR 
	LDR R1, =0x20 
	ldr r4, =0x40010C14 
	STR R1, [r4]             ;  GPIOB->BRR = 0x20; 
	
	;macRM68090_8BIT_DATAOUT(data&0xFF00);          	
	AND R1, R0, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0X00FF
	ORR R2, R1, R3
	ldr r4, =0x40010C0C 
	STR R2, [R4]
	
	;macRM68090_WR_CLR;macRM68090_WR_SET 
	LDR R1, =0x08
	ldr r4, =0x40010C14 
	STR R1, [R4]             ;GPIOB->BRR = 0x08; 
	ldr r4, =0x40010C10 
	STR R1, [R4]           ;GPIOB->BSRR = 0x08; 
	
	;macRM68090_8BIT_DATAOUT(((data<<8) &0xFF00));
	MOV R2, R0, LSL#8
	AND R2, R2, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0x00FF
	ORR R2, R0, R3
	ldr r4, =0x40010C0C 
	STR R2, [R4]
	
	;macRM68090_WR_CLR ;  
	ldr r4, =0x40010C14 
	STR R1, [r4]  ; GPIOB->BRR = 0x08;  
	
	;macRM68090_WR_SET ;macRM68090_CS_SET
	LDR R1, =0x28 
    ldr r4, =0x40010C10 	
	STR R1, [R4]  ; GPIOB->BSRR = 0x08; GPIOB->BSRR = 0x20; 
	
    BX LR
    NOP	
	END

KEIL MDK編譯警告:

warning: A1581W: Added 2 bytes of padding at address xxx

image

原因:

在Keil 裡寫彙編程式碼時如果程式碼尺寸不對齊,編譯器自動補補警告。

處理辦法:

加NOP指令,或修改對齊方式

 image


相關推薦

C語言調用匯彙編呼叫C語言

1.C語言調用匯編 程式的入口是main,在main裡調用匯編的函式。 在C語言中,要extern 一個函式宣告即可,然後這個函式在彙編裡面實現。 在彙編裡面,用EXPORT 把C語言定義的函式名引進來,再開始編寫函式名開始的段 #include<stdio.h

ARM組合語言——C語言調用匯語言實現字串拷貝

問題:編寫程式,實現將一個字串字串塊從一個位置複製到另外一個位置。並顯示源字串與複製後形成的字串。主程式用C語言編寫:實現源字串的定義,目的字串的定義,以及顯示功能。ARM彙編程式實現字串的複製。程式程式碼:C語言程式:#include <stdio.h> ex

C語言調用匯子過程時引數在棧中是如何呼叫

在C語言中嵌入彙編子過程的新手大多都會有一個問題,在用匯編寫的子過程(函式)中到底以怎樣的形式來獲取傳進來的引數呢?這裡討論的是堆疊法來實現,下面是我個人的理解:(大神可以一笑而過) 針對這個問題,首先得明白呼叫一個子過程時棧的變化,因為在傳參時首先是將引數壓入棧中,而子

常用的ARM彙編指令集與彙編呼叫C語言

***指令與偽指令: 指令:CPU機器指令的助記符,經過編譯後得到一串10組成的機器碼,可以被CPU直接讀取執行。 偽指令:編譯器環境提供,用來指導編譯過程,最終不會生成機器碼。 ***LDR/STR架構: CPU不能直接對記憶體的內容進行操作,必須藉助CPU

ARM彙編C語言混合程式設計之彙編呼叫C函式

呼叫沒有引數的函式 呼叫有引數的函式 總結 本文所用硬體平臺為S3C2440開發板。通過一個點亮數碼管的程式說明ARM彙編呼叫C函式的方法。 根據C語言中函式引數的個數,可以將彙編呼叫C函式分為兩種情況,呼叫沒有引數的函式和呼叫有引數的

C調用匯

例子:在C的main函式中調用匯編語言寫的addone函式,把傳入的引數加一然後返回。 彙編裡面首先要把用到的暫存器壓棧,使用指令global使函式可以在其他檔案中呼叫,順便說一句,C中的static函式之所以只能在本檔案中可用,就是編譯後的彙編檔案沒有用global指令,

用匯的眼光看C 開篇

                【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】       很多朋友,包括我自己在內,對C++語言的很多特性不是很明白。特別是幾年前找工作的時候,為了應付來自工作單位的考試,我經常逼著自己的去記住一些複雜的試題和答案。可

用匯的眼光看C++(之指標1)

                 【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】    指標是我們在C/C++中經常遇到的一種資料型別。指標用的好,可以提高程式碼的可讀性;但是如果使用不恰當,反而會造成很大的麻煩。指標,也就是指向某一種資料型別的地址。

彙編呼叫c函式為什麼要設定棧

4.舉例分析C語言函式呼叫是如何使用棧的 對於上面的解釋的棧的作用顯得有些抽象,此處再用例子來簡單說明一下,就容易明白了:用:arm-inux-objdump–d u-boot >dump_u-boot.txt可以得到dump_u-boot.txt檔案。該檔案就是中,包含了u-boot中的程式的可執行的

C++遲後聯虛擬函式表

先看一個題目: class Base { public: virtual void Show(int x) { cout << "In Base class, int x = " << x << endl; } }

C++的靜態聯動態聯技術

聯編是指一個計算機程式自身彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。 靜態聯編 靜態聯編是指聯編工作出現在編譯連線階段,這種聯編又稱早期聯編,因為這種聯編過程是在程式開始執行之前完成的。 在編譯時所進行的這種聯編又稱靜態束定。在編

函式調用匯程式碼分析

c語言程式碼和彙編後的彙編程式碼分別如下圖所示: 在main函式中返回值f(2)+1,所以首先呼叫f(2)函式,在呼叫f(2)函式之前要先儲存main函式目前的狀態,棧基址指標,棧指標 之間的內容是main函式執行存放在棧中的內容,保護這兩個暫存器之間的內容可以保證返回

一段C語言彙編的對應分析,揭示函式呼叫的本質

一段C語言和彙編的對應分析,揭示函式呼叫的本質 2018年09月30日 13:32:19 sdulibh 閱讀數:17 本文作者周平,原創作品轉載請註明出處 首先對會涉及到的一些CPU暫存器和彙編的基礎知識羅列一下:   16位、32位、64

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

這一 參數表 想要 return urn 類型 ring 符號表 參數 C語言與匯編語言相互調用原理以及實例 1.原理 其實不管是C語言還是匯編語言想要執行都是最終編譯鏈接成為二進制文件。 這裏一定要明確編譯和鏈接是兩個步驟,生成的文件格式也是不一樣的。 編譯生成的文件是一

nasm 彙編c 語言互相呼叫

NASM 與c 互動 Window nasm 彙編 與c 語言互相呼叫 Windows Linux c函式,提供給彙編使用 編譯過程 環境配置 nasm 彙編 與c 語言互相呼叫 nasm 在

詳解swiftOC以及C語言的混(不看後悔!)

前言:        Swift 語言出來後,可能新的專案直接使用swift來開發,但可能在過程中會遇到一些情況,某些已用OC寫好的類或封裝好的模組,不想再在swift 中再寫一次,或者有一些第三方使用OC寫的,沒有swift版本,怎麼辦?那就使用混編。這個在IOS8

Masm(611) 呼叫 第三方c語言函式(彙編呼叫第三方c語言函式庫)

一開始的程式碼: void print(){ printf("hello hairi"); } lib1的程式碼 include Lib1.lib data segment ;定義資料段 infon db 0dh,0ah,'Please input a year

用匯實現C庫函式的呼叫

title ccall .386.model flat,c.data?arg_num dword 0arg_tab dword 100 dup(0)arg_tye dword 100 dup(0)fun_ptr dword 0.codepush_arg_ini procmov arg_num, 0retpus

彙編除錯技巧:呼叫C語言函式printf()

除錯程式的痛苦莫過於除錯組合語言了~ 實際上對於一個嵌入式軟體工程師來說,組合語言的除錯跟C語言的除錯如出一轍。當然 ,也有些軟體可以用來模擬,例如real view, DS-5等等,但更為普通的情況是啥都沒有,接下來,本貼將介紹組合語言的列印除錯。 本帖主要內容有: 1.

使用匯語言實現if else 迴圈 函式呼叫

需要使用匯編來演示如下程式碼 需要下載ollydbg彙編偵錯程式 點選File-Open隨意開啟一個exe檔案 我這裡隨便找到c:/windows/explorer.exe檔案 這裡EIP的值表示下一次執行需要執行的程式碼位置 雙擊 EIP紅色地址 左邊程式碼會自動跳轉