當前位置:首頁 » 編程語言 » c語言內嵌arm匯編

c語言內嵌arm匯編

發布時間: 2022-10-09 19:30:18

Ⅰ arm中如何實現c語言與匯編語言的混合編程

如果你是想在一個文件里混寫c語言和arm匯編,這個跟編譯器有關系,如果你用gcc,可以用__asm__語法,請自行搜索__asm__相關資料

另一種方法,就是arm匯編文件和c語言文件分開來寫,在c語言中聲明函數符號即可。然後分別編譯後再用鏈接器鏈到一起

Ⅱ c語言內嵌arm匯編,實現1+2+…+100

#include<stdio.h>

intmain(intargc,constchar*argv[])
{
intdata=0,result=0;
__asm__ __volatile__(
"movl$0,%[data] "
"movl$0,%0 "
"loop1:"
"inc%[data] "
"addl%[data],%0 "
"cmp$100,%[data] "
"jneloop1 "

:"=r"(result),[data]"=r"(data) /*Rotationresult.*/
:/*Rotatedvalue.*/
:/*Noclobbers*/
);
printf("result=%d,data=%d ",result,data);
return0;
}

gcc 的內聯匯編 , 執行效果:

$ gcc main.c -o main

$ ./main

result = 5050, data = 100


希望你滿意!

Ⅲ arm編程,c語言中嵌入匯編實現1+2+3+...+100

C語言中static關鍵字的常見用法及舉例

在嵌入式系統開發中,目前使用的主要編程語言是C和匯編,

C++已經有相應的編譯器,但是現在使用還是比較少的。在稍大

規模的嵌入式軟體中,例如含有OS,大部分的代碼都是用C編

寫的,主要是因為C語言的結構比較好,便於人的理解,而且有

大量的支持庫。盡管如此,很多地方還是要用到匯編語言,例如

開機時硬體系統的初始化,包括CPU狀態的設定,中斷的使能,

主頻的設定,以及RAM的控制參數及初始化,一些中斷處理方

面也可能涉及匯編。另外一個使用匯編的地方就是一些對性能非

常敏感的代碼塊,這是不能依靠C編譯器的生成代碼,而要手工

編寫匯編,達到優化的目的。而且,匯編語言是和CPU的指令集

緊密相連的,作為涉及底層的嵌入式系統開發,熟練對應匯編語

言的使用也是必須的。

單純的C或者匯編編程請參考相關的書籍或者手冊,這里主要討

論C和匯編的混合編程,包括相互之間的函數調用。下面分四種

情況來進行討論,暫不涉及C++。

1. 在C語言中內嵌匯編

在C中內嵌的匯編指令包含大部分的ARM和Thumb指令,不過其

使用與匯編文件中的指令有些不同,存在一些限制,主要有下面

幾個方面:

a. 不能直接向PC寄存器賦值,程序跳轉要使用B或者BL指令

b. 在使用物理寄存器時,不要使用過於復雜的C表達式,避免物理寄存器沖突

c.
R12和R13可能被編譯器用來存放中間編譯結果,計算表達式值時可能將R0到R3、R12及R14用於子程序調用,因此要避免直接使用這些物理寄存器

d. 一般不要直接指定物理寄存器,而讓編譯器進行分配

內嵌匯編使用的標記是 __asm或者asm關鍵字,用法如下:

__asm

{

instruction [; instruction]



[instruction]

}

asm(「instruction [; instruction]」);

下面通過一個例子來說明如何在C中內嵌匯編語言,

#include

void my_strcpy(const char *src, char *dest)

{

char ch;

__asm

{

loop:

ldrb ch, [src], #1

strb ch, [dest], #1

cmp ch, #0

bne loop

}

}

int main()

{

char *a = "forget it and move on!";

char b[64];

my_strcpy(a, b);

printf("original: %s", a);

printf("ed: %s", b);

return 0;

}

在這里C和匯編之間的值傳遞是用C的指針來實現的,因為指針

對應的是地址,所以匯編中也可以訪問

2. 在匯編中使用C定義的全局變數

內嵌匯編不用單獨編輯匯編語言文件,比較簡潔,但是有諸多限

制,當匯編的代碼較多時一般放在單獨的匯編文件中。這時就需

要在匯編和C之間進行一些數據的傳遞,最簡便的辦法就是使用

全局變數。

/* cfile.c

* 定義全局變數,並作為主調程序

*/

#include

int gVar_1 = 12;

extern asmDouble(void);

int main()

{

printf("original value of gVar_1 is: %d", gVar_1);

asmDouble();

printf(" modified value of gVar_1 is: %d", gVar_1);

return 0;

}

對應的匯編語言文件

;called by main(in C),to double an integer, a global var defined in C

is used.

AREA asmfile, CODE, READONLY

EXPORT asmDouble

IMPORT gVar_1

asmDouble

ldr r0, =gVar_1

ldr r1, [r0]

mov r2, #2

mul r3, r1, r2

str r3, [r0]

mov pc, lr

END

3. 在C中調用匯編的函數

在C中調用匯編文件中的函數,要做的主要工作有兩個,一是在

C中聲明函數原型,並加extern關鍵字;二是在匯編中用

EXPORT導出函數名,並用該函數名作為匯編代碼段的標識,最

後用mov pc, lr返回。然後,就可以在C中使用該函數了。從

C的角度,並不知道該函數的實現是用C還是匯編。更深的原因

是因為C的函數名起到表明函數代碼起始地址的左右,這個和匯

編的label是一致的。

/* cfile.c

* in C,call an asm function, asm_strcpy

* Sep 9, 2004

*/

#include

extern void asm_strcpy(const char *src, char *dest);

int main()

{

const char *s = "seasons in the sun";

char d[32];

asm_strcpy(s, d);

printf("source: %s", s);

printf(" destination: %s",d);

return 0;

}

;asm function implementation

AREA asmfile, CODE, READONLY

EXPORT asm_strcpy

asm_strcpy

loop

ldrb r4, [r0], #1 ;address increment after read

cmp r4, #0

beq over

strb r4, [r1], #1

b loop

over

mov pc, lr

END

在這里,C和匯編之間的參數傳遞是通過ATPCS(ARM

Thumb Procere Call Standard)的規定來進行的。簡單的說就

是如果函數有不多於四個參數,對應的用R0-R3來進行傳遞,多

於4個時藉助棧,函數的返回值通過R0來返回。

4. 在匯編中調用C的函數

在匯編中調用C的函數,需要在匯編中IMPORT 對應的C函數名

,然後將C的代碼放在一個獨立的C文件中進行編譯,剩下的工

作由連接器來處理。

;the details of parameters transfer comes from ATPCS

;if there are more than 4 args, stack will be used

EXPORT asmfile

AREA asmfile, CODE, READONLY

IMPORT cFun

ENTRY

mov r0, #11

mov r1, #22

mov r2, #33

BL cFun

END

/*C file, called by asmfile */

int cFun(int a, int b, int c)

{

return a + b + c;

}

在匯編中調用C的函數,參數的傳遞也是通過ATPCS來實現

的。需要指出的是當函數的參數個數大於4時,要藉助stack,具

體見ATPCS規范

Ⅳ arm中c語言嵌套匯編中:"=&r"(a)什麼意思,=有時候就可以換成+實在不懂啊

p=&r跟*p=r區別&r是取變數r的地址,p=&r的意思是把變數r的地址賦給變數p,這種情況p一般是個指針。*p在等號左邊,表示對p指向的內存空間賦值

Ⅳ 求一匯編小程序!用ARM匯編語言完成一個C語言嵌入式匯編方式實現字元串(數組)拷貝的功能

#include< reg51.h>
#include< stdio.h>
#include< string.h>
#define INBUF_LEN 4 //數據長度
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3 , flag,temp,ch;
bit read_flag=0;
sbit cp=P1^1;
sbit DIR=P1^2;
int i;
unsigned int xdata *RAMDATA; /*定義RAM地址指針*/
unsigned char a[6] ={0x11,0x22,0x33,0x44,0x55,0x66} ;
void init_serialcomm(void)
{
SCON=0x50; //在11.0592MHz下,設置串列口波特率為9600,方式1,並允許接收
PCON=0x00;
ES=1;
TMOD=0x21; //定時器工作於方式2,自動裝載方式
TH0=(65536-1000)%256;
TL0=(65536-1000)/256;
TL1=0xfd;
TH1=0xfd;
ET0=1;
TR0=1;
TR1=1;
// TI=0;
EA=1;
// TI=1;
RAMDATA=0x1F45;
}
void serial () interrupt 4 using 3
{
if(RI)
{ RI=0;
ch=SBUF;
TI=1; //置SBUF空
switch(ch)
{
case 0x01 :printf("A"); TI=0;break;
case 0x02 :printf("B"); TI=0;break;
case 0x03 :printf("C"); TI=0;break;
case 0x04 :printf("D"); TI=0;break;
default :printf("fg"); TI=0;break;
}
}
}
//向串口發送一個字元
void timer0() interrupt 1 using 3{
// char i;
flag++;
TH0=0x00;
TL0=0x00;
if(flag==10)
{// cp=!cp;
// for(i=0;i<6;i++)
P2=0x25;
TI=1;
temp=*RAMDATA;
printf("%c",temp);
TI=0;
// RAMDATA--;
flag=0;
}
}
//主程序
main()
{
init_serialcomm(); //初始化串口
//向6264中送數據
{
*RAMDATA=0x33;
}
while(1)
{
*RAMDATA=0x33;;
}
}

Ⅵ 如何在C或C++代碼中嵌入ARM匯編代碼

C語言中嵌入匯編的方法是加入關鍵字「asm」來實現的,如: 例1: main() { asm mov ah,2; asm mov bh,0; asm mov dl, 20; asm mov dh,10; asm int 10h; } 例2: main() { asm{ mov ah,2; mov bh,0; mov dl, 20; mov dh,10; int 10h; } }

Ⅶ arm,c語言中嵌入ARM匯編,實現1+2+3+...+100

實在不會的話,先用C寫出來,然後再匯編調試界面看看匯編代碼,不是很難。

Ⅷ 如何在C語言中嵌入匯編

以下所說嵌入的匯編都是GUN 的C語言中嵌入ARM匯編。

1)2個參數的內嵌語句

這種形式的匯編用於簡單的語句,參數限制輸入和輸出語法格式如下:

asm(code : output operand list : inputoperand list : clobber list);

匯編和C語句這間的聯系是通過上面asm聲明中可選的output operand list和input operand list。Clobber list後面再講。

下面是將C語言的一個整型變數傳遞給匯編,邏輯左移一位後在傳遞給C語言的另外一個整型變數。

/* Rotating bits example */

asm("mov %[result], %[value], ror#1" : [result] "=r" (y) : [value] "r" (x));

每一個asm語句被冒號(:)分成了四個部分。

 匯編指令放在第一部分中的「」中間。

"mov %[result], %[value], ror #1"

 接下來是冒號後的可選擇的output operand list,每一個條目是由一對[](方括弧)和被他包括的符號名組成,它後面跟著限制性字元串,再後面是圓括弧和它括著的C變數。這個例子中只有一個條目。

[result] "=r" (y)

 接著冒號後面是輸入操作符列表,它的語法和輸入操作列表一樣

[value] "r" (x)

為了增加代碼的可讀性,你可以使用換行,空格,還有C風格的注釋。

asm("mov %[result], %[value], ror#1"

: [result]"=r" (y) /* Rotation result. */

: [value]"r" (x) /* Rotated value. */

: /* No clobbers */

);

在代碼部分%後面跟著的是後面兩個部分方括弧中的符號,它指的是相同符號操作列表中的一個條目。

%[result]表示第二部分的C變數y,%[value]表示三部分的C變數x;

符號操作符的名字使用了獨立的命名空間。這就意味著它使用的是其他的符號表。簡單一點就是說你不必關心使用的符號名在C代碼中已經使用了。在早期的C代碼中,循環移位的例子必須要這么寫:

asm("mov %0, %1, ror #1" :"=r" (result) : "r" (value))

在匯編代碼中操作數的引用使用的是%後面跟一個數字,%1代表第一個操作數,%2代碼第二個操作數,往後的類推。這個方法目前最新的編譯器還是支持的。但是它不便於維護代碼

實例代碼:

2) 帶.s文件的匯編

編譯命令:

arm-linux-gcc main.cAsmfile_gnu.s -o mains

main.c

#include<stdio.h>

extern voidpcm8_2_pcm16(unsigned char* pIn, int nInlen, short* pOut);

extern voidpcm16_2_pcm8(short* pIn, int nInlen,unsigned char* pOut);

int main()

{

unsigned char* pIn="1234";

short pInd[256];

unsigned char pOutd[256];

int nInlen=4;

int i = 0;

short pOut[256];

for(i=0;i<4;i++)

printf(" 0x%x ",pIn[i]);

printf(" ");

memset((char *)pOut,0,256*2);

memset((char *)pInd,0,256*2);

memset((char *)pOutd,0,256*2);

pcm8_2_pcm16(pIn,nInlen,pOut);

for(i=0;i<4;i++)

printf(" 0x%x ",pOut[i]);

printf(" ");

memcpy((char *)pInd,(char *)pOut,256*2);

pcm16_2_pcm8(pInd,nInlen,pOutd);

for(i=0;i<4;i++)

printf(" 0x%x ",pOutd[i]);

printf(" ");

return 0;

}

Asmfile_gnu.s

.text

.global pcm8_2_pcm16

.global pcm16_2_pcm8

#*******************************#

#********* ENCODER 實現將第一個輸入參數

#左移8位然後異或0x8000 然後拷貝到第三個參數

#DECODE 取第一個參數所指的數據先異或0x8000

#然後右移8位將數據拷貝到第三個參數

#*******************************

pcm8_2_pcm16:

MOV R6,#0

MOV R7,#0

ENCODER:

LDRB R5,[R0,R6]

MOV R8,R5,LSL#8

EOR R9,R8,#0x8000

STRH R9,[R2,R7]

ADD R7,R7,#2

ADD R6,R6,#1

SUB R1,R1,#1

CMP R1,#0

BNE ENCODER

B OVER

pcm16_2_pcm8:

MOV R6,#0

MOV R7,#0

DECODE:

LDRH R5,[R0,R6]

EOR R8,R5,#0x8000

MOV R9,R8,LSR#8

STRB R9,[R2,R7]

ADD R7,R7,#1

ADD R6,R6,#2

SUB R1,R1,#1

CMP R1,#0

BNE DECODE

OVER:

.end

Ⅸ arm匯編裡面,對這處理器的操作可以用c語言嗎比方說這條指令 mcr p15,0, r4,c2,

不可以,這是協處理器指令,不能用c語言只能用匯編

熱點內容
linuxftp下載代碼 發布:2024-12-22 01:17:44 瀏覽:973
玩游戲平板安卓哪個性價比高 發布:2024-12-22 01:16:21 瀏覽:166
python查看類函數 發布:2024-12-22 01:15:31 瀏覽:41
詛咒密碼的第二塊碎片維內拉圖斯在哪裡 發布:2024-12-22 00:57:13 瀏覽:900
雲存儲伺服器管理系統 發布:2024-12-22 00:44:11 瀏覽:474
安卓系統推薦廣告怎麼關閉 發布:2024-12-22 00:42:50 瀏覽:863
蘋果ipad瀏覽器沒有伺服器怎麼辦 發布:2024-12-22 00:32:52 瀏覽:680
linux操作系統是什麼系統 發布:2024-12-22 00:30:46 瀏覽:89
linux密碼忘了怎麼辦 發布:2024-12-22 00:24:44 瀏覽:258
崩壞學園2金立伺服器是什麼 發布:2024-12-22 00:23:25 瀏覽:586