當前位置:首頁 » 編程語言 » c語言如何調用匯編函數
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言如何調用匯編函數

發布時間: 2022-11-05 16:57:44

㈠ 誰知道匯編與c語言怎樣互相調用啊,還有怎樣在linux編譯啊,如果可以的話,就寫個簡單的程序介紹。謝謝哈

對於C和匯編語言的介面主要有兩個問題需要解決。
一、調用者與被調用者的參數傳遞
這種數據傳遞通過堆棧完成,在執行調用時從調用程序參數表中的最後一個參數開始 ,自動依次壓入堆棧;將所有參數壓入堆棧後,再自動將被調用程序執行結束後的返回地址 (斷點)壓入堆棧,以使被調程序結束後能返回主調程序的正確位置而繼續執行。例如一調用名為add匯編程序模塊的主函數:main( ){...... add(dest,op1,op2,flages);......}。在此例中對主函數進行反匯編,主函數在調用add函數前自動組織的堆棧。
.
.
.
lea 0xfffffffe8(%ebp),%eax #flages數組的首地址入棧
push %eax
pushl 0xfffffff8(%ebp) #OP2入棧
pushl 0xfffffffc(%ebp) #OP1 入棧
pushl 0xfffffff0(%ebp) #dest地址入棧
call 0x80483f0 <add> #調用add函數
.
.

進入匯編子程序後,為了能正確獲取主調程序並存入堆棧中的數據,被調的匯編子程序先後要做如下一些工作:
1、 保存esp的副本
進入匯編子程序後,子程序中免不了要有壓棧和出棧的操作,故ESP時刻在變化。為了能用 ESP訪問堆棧中的參數,安全辦法是一進入子程序後,先為ESP制副本,以後對傳遞參數的訪問 都用副本進行。一般可用EBP保存ESP,如:
push %ebp
mov %ebp,%esp
2、保留數據空間
如果匯編子程序中需要一些局部數據,可以簡單地減小ESP的值,以便在棧空間中保留出一段存貯區,用於存放局部數據,該區域須在子程序結束後恢復。如下語句可以保留一個局部數據區:
push %ebp
mov %ebp ,%esp
subl space,%esp;設space=4
movl $0x0,%ebp
movl $0x0,-2(%ebp)
如上語句段中,space是局部數據的總位元組數。在以後的應用中,由於ESP是變化的,而 EBP是 固定的,用負偏移量可以存取局部變數。上例利用EBP及偏移量,將兩個字的局部數 據初始化為0。
3、保留寄存器值
如果在被調子程序中用到ESI、EDI等其它寄存器,則應先把它們壓入堆棧,以保留寄存器原值 。例如,下例就是將ESI和EDI寄存器的值壓棧:
pushl %ebp
movl %ebp ,%esp
subl $space ,%esp,
pushl %esi
pushl %edi
4、獲取傳遞參數
作完了1~3步的操作後,結合上面C程序傳送參數這一例子,現在棧結構如圖二所示。

由此可見,EBP保留了ESP在參數傳遞完並將EBP壓棧後的一個副本,利用EBP可以很方便地訪問各參數。現假設各參數都是2位元組的整數值,在小模式編譯方式共佔用2個位元組。如果要將傳遞的參數op1、op2取出,並分別賦給ebx、ecx寄存器,可由下列語句完成這一功能:
movl 0x8(%ebp),%eax
movl 0xc(%ebp),%ecx
5、子程序返回值
當子程序的執行結果需要返回時,根據返回值的字長,C按如下約定接收返回值:1位元組在AL 寄存器中;2位元組在EAX寄存器中;4位元組則高位部分在EDX中、低位部分在EAX寄存器中。C可從這些寄存器中取出返回值。
6、退出匯編子程序
結束匯編子程序的步驟如下:
1) 若ESS、EDS、ESI或EDI已被壓棧,則需按保存它們的相反順序彈出它們。
2) 若在過程開始時分配了局部數據空間,則以指令 mov %esp和%ebp 恢復%esp。
3) 以指令pop %ebp 恢復%ebp ,該步是必須的。或者可以用leave語句來恢復%ebp 。它相當於movl %ebp, %esp; popl %ebp
4) 最後以ret結束匯編程序。
二、 說明和建立調用者與被調用者間的連系
為了建立調用與被調用模塊間的連接關系,被調用的匯編程序應用global,說明其可被外部模塊調用;而調用程序則應預先說明要引用的外部模塊名。下面通過我的例子進行說明,該例是C調用add0的匯編子程序。程序清單如下:
/* add.c */
#include <stdio.h>
extern void add(int *dest,int op1,int op2,short int*flages);
/*聲明調用外部的匯編函數*/
int main(void){
int op1,op2,result;
int *dest=&result;
short int flages[4]={0,0,0,0};
printf("please enter two soure operater:");
scanf("%x%x",&op1,&op2);
add(dest,op1,op2,flages);/*調用add0函數*/
printf("The result of ADD is :%x/n flages N(negative) Z(zero) C(carry) V(overflow:%d,%d,%d,%d/n",*dest,flages[3],flages[2],flages[1],flages[0]);
return 0;
}
#add.s
.text
.align 2
.global add
.type add,function
#定義add為外部可調用的函數
add:
push %ebp #ebp寄存器內容壓棧,保存add函數的上級調用函數的棧基地址
mov %esp,%ebp #esp值賦給ebp,設置add函數的棧基地址
mov 0x8(%ebp),%edx
mov 0x10(%ebp),%eax
add 0xc(%ebp),%eax
mov %eax,(%edx)
mov 0x14(%ebp),%eax
jo OF
C:
jc CF
S:
js SF
jz ZF
jmp out
OF:
movw $0x1,(%eax)
jmp C
CF:
movw $0x1,0x2(%eax)
jmp S
SF:
movw $0x1,0x6(%eax)
movw $0x0,0x4(%eax)
jmp out
ZF:
movw $0x1,0x4(%eax)
movw $0x0,0x6(%eax)
out:
leave #將ebp值賦給esp,pop先前棧內的上級函數棧的基地址給#ebp,恢復原棧基址
ret #add函數返回,回到上級的調用函數

其中.text 標志一個代碼段的開始,這是AT&T的段格式;global add;/n
type add,function說明add是公用的,可以由外部其它單獨編譯模塊調用。
將C源程序以文件名add.c存檔,匯編語言源程序以add.s 存檔;通過MAKE進行編譯和連接連接代碼如下:

all: myadd
myadd: adds.o addc.o
gcc –o myadd adds.o adc.o
adds.o: add.s
as –o adds.o add.s
addc.o: add.c
gcc –g –o addc.o add.c
由上可見,在C中調用匯編模塊很方便。所以我們在實際軟體開發中,可以採用混合編程的技術,從而盡可能利用各語言的優勢。既滿足實際問題的需要,又簡化設計過程,達到事半功倍的效果。

㈡ 在c語言里怎麼調用匯編函數

把匯編寫在另一個文件里在main寫個原型聲明再把兩個文件同時編譯可不可以。
我的gcc編譯器里是這樣寫的
匯編文件m.s
.file "stdio.h"
#hellowrold.s print "hello,world!"

.section .data
output:
.ascii "%d %d %d\0"

.section .text
.globl _fun
_fun:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 0x8(%ebp), %eax
movl %eax, 0x4(%esp)
movl 0xc(%ebp), %eax
movl %eax, 0x8(%esp)
movl 0x10(%ebp), %eax
movl %eax, 0xc(%esp)
movl $output, %eax
movl %eax, (%esp)
call _printf
movl %ebp, %esp
popl %ebp
ret
.end
主函數前的原型聲明 extern int fun(int i, int j, int k);

㈢ 如何在C語言中調用匯編函數

1、 參數傳遞

二、匯編程序、C程序相互調用舉例
1、 C程序調用匯編程序
匯編程序的設計要遵守ATPCS(ARM—Thumb Procere Call Standard),保證程序調用時參數的正確傳遞。在匯編程序中使用EXPORT 偽操作聲明本程序,使得本程序可以被別的程序調用。在C程序使用extern聲明該匯編程序。
下面是一個C程序調用匯編程序的例子。其中匯編程序str實現字元串復制功能,C程序調用str完成字元串復制的工作。

㈣ 如何用匯編實現C語言函數調用

1。對於「匯編調用」:
我知道你要調用func,而不是它本身,但如果這個函數比較復雜時是必須用逆向先分析func這個函數,然後再確定參數列表和返回值的……

2。對於你的內聯匯編的代碼:
這里到底要不要用add %3, %%rsp;還是一個問題,因為要看函數使用的是什麼調用標准,有標准C的,VB的,Pascal的,包括fastcall,stdcall,cdecl等……

3。對於「知道函數參數的起始地址和長度」:
這個的話,除了參數中有字元數組和直接結構體什麼的,所有的基本變數基本都是每8位元組(64位)一個,並且Intel一般都用bigendian的,也就是說,在內存中 01 02 03 04 05 06 07 08 讀入寄存器後會變為: 0x0807060504030201
所以說對於簡單的函數,用8位元組一個參數來做就好了……
而對於有字元數組什麼的就必須用逆向分析了……

這個……只能進行逆向分析了……
反正你知道了函數的地址和長度……
就是你把編譯為機器碼的程序用反編譯工具翻譯成匯編,然後分析一下就好了,C語言的匯編還是比較簡單……
比如這個函數:
int func(int a, int* b) {
// float要用到CPU的FPU,指令記不得,要查下
// 為了簡單就改為int*
printf("a = %d, b = %d\n", a, *b);
return a;
}
編譯成機器碼後,反編譯,如果不加優化,一般都會這樣:
(假設函數入口地址為0400000h)
sub_0400000:
push rbp
mov rbp,rsp ; C函數參數度取使用堆棧式

; 參數在內存中這樣: |...| a | b | ... |
; 由於是64位,故8位元組對齊
mov rax,[rbp+8] ; rax = *(rbp+8) // 這里就是 rax = a
push rsi
mov rsi,[rbp+16] ; rsi = *(rbp+16) // rsi = b

; 調用C函數都是這樣堆棧式,最後一個參數最先入棧
push [rsi]
push rax
push "a = %d, b = %d\n" ; 這里是便於理解,實際上是push這個字元串常量的指針
call printf ; printf("a = %d, b = %d\n",rax,*rsi)
add rsp,24 ; 平衡堆棧,用了3個參數,要還原3*8=24位元組,但根據函數類型的不同去平衡,像調用VB的函數就不需要平衡堆棧……

; 還原數據
mov rsp,rbp
pop rsi
pop rbp

; 一般返回數據都用rax裝載
mov rax,[rbp+8] ;rax=a
ret ; return rax

想調用未知參數列表的函數就是把以上過程倒過來,看著匯編把C的代碼寫出來……
破解注冊碼什麼也是這樣玩的……
實際上你可以直接用反編譯的軟體,比如IDA,直接自動分析,它反編譯的雖然是匯編,但參數列表還是大部分都顯示的……
但是,當編譯器加優化大部分情況就必須自己分析了,因為:
int func(int a, int* b) {
printf("a = %d, b = %d\n", a, *b);
return a;
}
在優化情況下可能為(直接用寄存器傳遞數據):
sub_040000:
push rdx
mov rdx,rax
push rax
push rbx
push "a = %d, b = %d\n"
call printf
mov rax,rdx
pop rdx
ret

其實像www.pediy.com看雪學院有不少這方面的教程……

㈤ C語言和匯編語言的相互調用

這不是很復雜。

一個.c,一個.asm

int__stdcallPlusOne(int*i)
{
returni+1;
}

.asm

.386
.modelflat,stdcall
optioncasemap:none
includewindows.inc
includeuser32.inc
includekernel32.inc
includelibuser32.lib
includelibkernel32.lib
PlusOneprotoa:DWORD
.data
numdd0x30
.code
start:
invokePlusOne,offsetnum;0x31ASCII:'1'
invokeMessageBox,0,offsetnum,offsetnum,MB_OK
invokeExitProcess,0
endstart

直接上代碼。

分別ml和cl

得到.obj目標文件,然後執行

link -subsystem:windows 兩個目標文件名

得到.exe

===========================

備註:代碼有可能編譯出錯。。。臨時寫的,未經測試

如果打開目標文件,你就會發現兩邊都有「_PlusOne@4」如果沒有,可以追問我改代碼

【滑稽】

c中調用匯編也差不多,注意調用規則要相同。

另外,匯編函數名要加下劃線「_」

別忘了採納!!!

我用的masm32

㈥ C語言如何調用無參數的匯編語言

匯編語言的過程調用是直接跳轉到相應的函數,參數需要自己填寫並壓棧或者用寄存器傳參。
c語言關於傳參和返回這部分,由編譯器替程序員完成了。
不明白可以追問,望採納。

㈦ C語言和匯編語言的相互調用

淺談C程序中調用匯編模塊的方法

C語言是目前非常流行的一種編程語言,除具有高級語言使用方便靈活、數據處理能力強、 編程簡單等優點外,還可實現匯編語言的大部分功能,如可直接對硬體進行操作、生成的 目標代碼質量較高且執行的速度較快等。所以在工程上對硬體處理速度要求不很高的情況下, 基本可以用C代替匯編語言,編寫介面電路的控制軟體。但C也不能完全取代匯編語言,如在一些對速度要求很高的實時控制系統中,以及對硬體的特殊控制方面,C有時也不能完全很好勝任,還需要匯編語言來編寫。因為匯編語言目標代碼更精練,對硬體直接控制能力更強和執行速度更快,但匯編語言編程煩難、表達能力差也顯而易見。比較好的解決辦法是C與匯編語言混合編程,即用C編寫軟體的調度程序、用戶界面以及速度要求不高的控制部分,而用匯編語言對速度敏感部分提供最高速度的處理模塊,供C調用。這種方法提供了最佳的軟體設計方案,做到了兼顧速度效率高和靈活方便。由於本人的畢業設計需要C程序中調用匯編模塊的方法來提高ARM定點指令的執行速度,故對這方面進行了學習。學習心得如下:

對於C和匯編語言的介面主要有兩個問題需要解決。
一、調用者與被調用者的參數傳遞
這種數據傳遞通過堆棧完成,在執行調用時從調用程序參數表中的最後一個參數開始 ,自動依次壓入堆棧;將所有參數壓入堆棧後,再自動將被調用程序執行結束後的返回地址 (斷點)壓入堆棧,以使被調程序結束後能返回主調程序的正確位置而繼續執行。例如一調用名為add匯編程序模塊的主函數:main( ){...... add(dest,op1,op2,flages);......}。在此例中對主函數進行反匯編,主函數在調用add函數前自動組織的堆棧。
.
.
.
lea 0xfffffffe8(%ebp),%eax #flages數組的首地址入棧
push %eax
pushl 0xfffffff8(%ebp) #OP2入棧
pushl 0xfffffffc(%ebp) #OP1 入棧
pushl 0xfffffff0(%ebp) #dest地址入棧
call 0x80483f0 <add> #調用add函數
.
.
執行完add調用語句後,棧內數據結果如圖一所示。

進入匯編子程序後,為了能正確獲取主調程序並存入堆棧中的數據,被調的匯編子程序先後要做如下一些工作:
1、 保存esp的副本
進入匯編子程序後,子程序中免不了要有壓棧和出棧的操作,故ESP時刻在變化。為了能用 ESP訪問堆棧中的參數,安全辦法是一進入子程序後,先為ESP制副本,以後對傳遞參數的訪問 都用副本進行。一般可用EBP保存ESP,如:
push %ebp
mov %ebp,%esp
2、保留數據空間
如果匯編子程序中需要一些局部數據,可以簡單地減小ESP的值,以便在棧空間中保留出一段存貯區,用於存放局部數據,該區域須在子程序結束後恢復。如下語句可以保留一個局部數據區:
push %ebp
mov %ebp ,%esp
subl space,%esp;設space=4
movl $0x0,%ebp
movl $0x0,-2(%ebp)
如上語句段中,space是局部數據的總位元組數。在以後的應用中,由於ESP是變化的,而 EBP是 固定的,用負偏移量可以存取局部變數。上例利用EBP及偏移量,將兩個字的局部數 據初始化為0。
3、保留寄存器值
如果在被調子程序中用到ESI、EDI等其它寄存器,則應先把它們壓入堆棧,以保留寄存器原值 。例如,下例就是將ESI和EDI寄存器的值壓棧:
pushl %ebp
movl %ebp ,%esp
subl $space ,%esp,
pushl %esi
pushl %edi
4、獲取傳遞參數
作完了1~3步的操作後,結合上面C程序傳送參數這一例子,現在棧結構如圖二所示。

由此可見,EBP保留了ESP在參數傳遞完並將EBP壓棧後的一個副本,利用EBP可以很方便地訪問各參數。現假設各參數都是2位元組的整數值,在小模式編譯方式共佔用2個位元組。如果要將傳遞的參數op1、op2取出,並分別賦給ebx、ecx寄存器,可由下列語句完成這一功能:
movl 0x8(%ebp),%eax
movl 0xc(%ebp),%ecx
5、子程序返回值
當子程序的執行結果需要返回時,根據返回值的字長,C按如下約定接收返回值:1位元組在AL 寄存器中;2位元組在EAX寄存器中;4位元組則高位部分在EDX中、低位部分在EAX寄存器中。C可從這些寄存器中取出返回值。
6、退出匯編子程序
結束匯編子程序的步驟如下:
1) 若ESS、EDS、ESI或EDI已被壓棧,則需按保存它們的相反順序彈出它們。
2) 若在過程開始時分配了局部數據空間,則以指令 mov %esp和%ebp 恢復%esp。
3) 以指令pop %ebp 恢復%ebp ,該步是必須的。或者可以用leave語句來恢復%ebp 。它相當於movl %ebp, %esp; popl %ebp
4) 最後以ret結束匯編程序。
二、 說明和建立調用者與被調用者間的連系
為了建立調用與被調用模塊間的連接關系,被調用的匯編程序應用global,說明其可被外部模塊調用;而調用程序則應預先說明要引用的外部模塊名。下面通過我的例子進行說明,該例是C調用add0的匯編子程序。程序清單如下:
/* add.c */
#include <stdio.h>
extern void add(int *dest,int op1,int op2,short int*flages);
/*聲明調用外部的匯編函數*/
int main(void){
int op1,op2,result;
int *dest=&result;
short int flages[4]={0,0,0,0};
printf("please enter two soure operater:");
scanf("%x%x",&op1,&op2);
add(dest,op1,op2,flages);/*調用add0函數*/
printf("The result of ADD is :%x\n flages N(negative) Z(zero) C(carry) V(overflow:%d,%d,%d,%d\n",*dest,flages[3],flages[2],flages[1],flages[0]);
return 0;
}
#add.s
.text
.align 2
.global add
.type add,function
#定義add為外部可調用的函數
add:
push %ebp #ebp寄存器內容壓棧,保存add函數的上級調用函數的棧基地址
mov %esp,%ebp #esp值賦給ebp,設置add函數的棧基地址
mov 0x8(%ebp),%edx
mov 0x10(%ebp),%eax
add 0xc(%ebp),%eax
mov %eax,(%edx)
mov 0x14(%ebp),%eax
jo OF
C:
jc CF
S:
js SF
jz ZF
jmp out
OF:
movw $0x1,(%eax)
jmp C
CF:
movw $0x1,0x2(%eax)
jmp S
SF:
movw $0x1,0x6(%eax)
movw $0x0,0x4(%eax)
jmp out
ZF:
movw $0x1,0x4(%eax)
movw $0x0,0x6(%eax)
out:
leave #將ebp值賦給esp,pop先前棧內的上級函數棧的基地址給#ebp,恢復原棧基址
ret #add函數返回,回到上級的調用函數

其中.text 標志一個代碼段的開始,這是AT&T的段格式;global add;\n
type add,function說明add是公用的,可以由外部其它單獨編譯模塊調用。
將C源程序以文件名add.c存檔,匯編語言源程序以add.s 存檔;通過MAKE進行編譯和連接連接代碼如下:

all: myadd
myadd: adds.o addc.o
gcc –o myadd adds.o adc.o
adds.o: add.s
as –o adds.o add.s
addc.o: add.c
gcc –g –o addc.o add.c
由上可見,在C中調用匯編模塊很方便。所以我們在實際軟體開發中,可以採用混合編程的技術,從而盡可能利用各語言的優勢。既滿足實際問題的需要,又簡化設計過程,達到事半功倍的效果。

㈧ C語言如何調用無參數的匯編語言

;首先在程序存儲區中定義段,接著利用PUBLIC
;把函數聲明為公共函數,RSEG為匯編函數起始標志
;符,之後緊接匯編程序。為了實現程序的相互調用,
;要求匯編程序必須遵循C51函數名的轉換規則,函
;數必須以「?PR?函數名?模塊名」格式命名,否則
;將無法實現程序的相互調用。
NAME ONE
?PR?DELAY?ONE SEGMENT CODE
PUBLIC DELAY //不能用DELAY_MS, _在匯編里不能作為名字

RSEG ?PR?DELAY?ONE
DELAY:

RET
END

1樓的辦法是內嵌的辦法,也可以採用,但還要設置如下:
在Project 窗口中包含匯編代碼的C 文件上點擊右鍵, 選擇
「Options for ...」, 然後在彈出的窗口中選中「Generate Assembler SRC
File」和「Assemble SRC File」兩項。

㈨ 如何C語言與匯編混編

1.在C中內嵌匯編語句

在#pragma asm 與#pragma endasm 中加入要內嵌的匯編語句

例子:

#include <reg52.h>

void main()

{

P0^1=1;

#pragma asm

匯編延時程序

#pragma endasm

P0^1=0;

}

2.C程序調用匯編

(1)C文件格式

C程序調用匯編函數之前必須先用extern對函數加以聲明

例子:

#include<reg51.h>

extern void DLY1s();

void main()

{

P2=0xff;

DLY1s();

P2=0;

}

(2)匯編文件格式

用NAME定義模塊名,PUBLIC聲明為公共函數,RESG為匯編函數起始標志

例子1:

;;************************************
;Delay time 1s
;;************************************
NAME DLY1s ;定義模塊名
PUBLIC DLY1s ;聲明為公共函數
SEG_DLY1s SEGMENT CODE ;在程序存儲區中定義段
USING 1

RSEG SEG_DLY1s ;函數起始位置
;;--------------------------
DLY1s: SETB RS0
MOV R4,#04H
DLY100: MOV R3,#0FFH
DLY101: MOV R2,#0FFH
DLY102: NOP
NOP
DJNZ R2,DLY102
DJNZ R3,DLY101
DJNZ R4,DLY100
CLR RS0
RET
;;-----------------------------------
END
例子2:

;;************************************
;Delay time 10ms
;;************************************
NAME DLY10ms
PUBLIC DLY10ms
SEG_DLY10ms SEGMENT CODE
USING 1

RSEG SEG_DLY10ms
;;--------------------------
DLY10ms: SETB RS0
MOV R3,#32H
DLY101: MOV R2,#31H
DLY102: NOP
NOP
DJNZ R2,DLY102
DJNZ R3,DLY101
CLR RS0
RET
;;-----------------------------------
END

3.匯編調用C函數

(1)匯編文件格式

EXTRN CODE(function) ;聲明所要調用的C函數

ORG 0000H

LJMP MAIN

ORG 0030H

MAIN:MOV 30H,#5

MOV 31H,#6

CALL function ;調用C函數

MOV P2,32H

END

(2)C文件格式

#include <reg51.h>

#include <absacc.h>

void function()

{

DBYTE[0x32]=DBYTE[0x30]+DBYTE[0x31];

}

註:該方法簡單且容易掌握,卻有存儲空間使用效率低的缺點,但在項目對存儲空間需求較低的情況下,該方法是一個不錯的選擇。

4通過寄存器傳遞參數的混合調用

相互之間的調用必須滿足上述C調匯編和匯編調C的規則

例子1 C調用匯編:

C文件:

#include <reg51.h>
unsigned int ADD1(unsigned int a,unsigned int b)
void main()
{
unsigned int c;
c=ADD1(100,100);
}

匯編文件:

NAME _ADD1
PUBLIC _ADD1
SEG_ADD1 SEGMENT CODE
USING 1
RSEG SEG_ADD1

_ADD1:
MOV A,R5
ADD A,R7
MOV R7,A
MOV A,R4
ADDC A,R6
MOV R6,A
RET
END

註:當通過寄存器傳遞參數時在匯編里定義函數要用「_函數名」來定義函數

例子2 匯編調用C:

匯編文件:

EXTRN CODE(_function) ;聲明所要調用的C函數,通過寄存器則函數為_function
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN: MOV R7,#5 ;把所要傳送的值放入響應寄存器單元
MOV R5,#6
CALL _function
MOV A,R7
END

C文件:
#include <reg51.h>
unsigned char function(unsigned char a,unsigned char b)
{
return(a+b);
}

㈩ Keil中C語言調用匯編函數

1、在 C 文件中要嵌入匯編代碼片以如下方式加入匯編代碼:
#pragma ASM
; Assembler Code Here
#pragma ENDASM

2、在 Project 窗口中包含匯編代碼的 C 文件上右鍵,選擇「Options for ...」,點擊右邊的「Generate Assembler SRC File」
和「Assemble SRC File」,使檢查框由灰色變成黑色(有效)狀態;

3、根據選擇的編譯模式,把相應的庫文件(如 Small 模式時,是 Keil\C51\Lib\C51S.Lib)加入工程中, 該文件必須作為工程的最
後文件;