當前位置:首頁 » 編程語言 » linuxc嵌入匯編語言

linuxc嵌入匯編語言

發布時間: 2022-09-04 21:18:18

1. c語言內嵌匯編

在調試聯盛德W800晶元代碼時,看到了下面的代碼實現,記錄下C語言內嵌匯編語言的實現方式。部分代碼如下:

該函數實現功能:將入參newMask的值寫入到psr寄存器,用於恢復現場。

代碼下載路徑:http://www.winnermicro.com/html/1/156/158/558.html

__asm__ (

匯編語句部分

:輸出部分

:輸入部分

:破壞描述部分

);

1)C內嵌匯編以關鍵字 __asm__ 或 asm 開始。如果使用 volatile 關鍵字,則表示告訴編譯器不優化後續的代碼。

2) 匯編語句部分:可以包含多條匯編語句,每條語句之間用「 」或「;」,例:

註:匯編語句中的操作數可以使用佔位符引用C語言變數,名稱如下:%0,%1,…。

2) 輸出部分:在匯編語言中被修改的C變數

3) 輸入部分:作為參數輸入到匯編語言中的C變數

註:輸出和輸入部分是針對匯編語句部分的輸入和輸出參數而言。例:如果匯編語言使用變數設置寄存器,則用輸入部分;如果匯編語言從寄存器讀取值,保存到變數,則用輸出部分。

4) 破壞描述部分:通知編譯器使用了哪些寄存器或內存。

5) 每個部分之間用」:」隔開。匯編語句部分必不可少,其他部分可以省略。例: asm("nop") ,實現空操作。

2. 如何在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

3. 如何自學Linux下C語言嵌入式編程詳細點謝謝!書籍及開發板用什麼的最好

開發板用友善之臂的吧
mini2440 連3.5寸屏500塊錢的樣子
有好幾張DVD學習光碟

這款口碑比較高

嵌入式Linux操作系統學習規劃
ARM+LINUX路線,主攻嵌入式Linux操作系統及其上應用軟體開發目標:
(1) 掌握主流嵌入式微處理器的結構與原理(初步定為arm9)
(2) 必須掌握一個嵌入式操作系統 (初步定為uclinux或linux,版本待定)
(3) 必須熟悉嵌入式軟體開發流程並至少做一個嵌入式軟體項目。
從事嵌入式軟體開發的好處是:
(1)目前國內外這方面的人都很稀缺。這一領域入門門檻較高,所以非專業IT人員很難切入這一領域;另一方面,是因為這一領域較新,目前發展太快,大多數人無條件接觸。
(2)與企業計算等應用軟體不同,嵌入式領域人才的工作強度通常低一些(但收入不低)。
(3)哪天若想創業,搞自已的產品,嵌入式不像應用軟體那樣容易被盜版。硬體設計一般都是請其它公司給訂做(這叫「貼牌」:OEM),都是通用的硬體,我們只管設計軟體就變成自己的產品了。
(4)興趣所在,這是最主要的。
從事嵌入式軟體開發的缺點是:
(1)入門起點較高,所用到的技術往往都有一定難度,若軟硬體基礎不好,特別是操作系統級軟體功底不深,則可能不適於此行。
(2)這方面的企業數量要遠少於企業計算類企業。
(3)有少數公司經常要碩士以上的人搞嵌入式,主要是基於嵌入式的難度。但大多數公司也並無此要求,只要有經驗即可。
(4)平台依託強,換平台比較辛苦。
興趣的由來:
1、成功觀念不同,不虛度此生,就是我的成功。
2、喜歡思考,挑戰邏輯思維。
3、喜歡C
C是一種能發揮思維極限的語言。關於C的精神的一些方面可以被概述成短句如下:
相信程序員。
不要阻止程序員做那些需要去做的。
保持語言短小精幹。
一種方法做一個操作。
使得它運行的夠快,盡管它並不能保證將是可移植的。
4、喜歡底層開發,討厭vb類開發工具(並不是說vb不好)。
5、發展前景好,適合創業,不想自己要死了的時候還是一個工程師。
方法步驟:
1、基礎知識:
目的:能看懂硬體工作原理,但重點在嵌入式軟體,特別是操作系統級軟體,那將是我的優勢。
科目:數字電路、計算機組成原理、嵌入式微處理器結構。
匯編語言、C/C++、編譯原理、離散數學。
數據結構和演算法、操作系統、軟體工程、網路、資料庫
方法:雖科目眾多,但都是較簡單的基礎,且大部分已掌握。不一定全學,可根據需要選修。
主攻書籍:the c++ programming language(一直沒時間讀)、數據結構-C2。

2、學習linux:
目的:深入掌握linux系統。
方法:使用linux—〉linxu系統編程開發—〉驅動開發和分析linux內核。先看深,那主講原理。看幾遍後,看情景分析,對照深看,兩本交叉,深是綱,情是目。剖析則是0.11版,適合學習。最後深入代碼。
主攻書籍:linux內核完全剖析、unix環境高級編程、深入理解linux內核、情景分析和源代。
3、學習嵌入式linux:
目的:掌握嵌入式處理器其及系統。
方法:(1)嵌入式微處理器結構與應用:直接arm原理及匯編即可,不要重復x86。
(2)嵌入式操作系統類:ucOS/II簡單,開源,可供入門。而後深入研究uClinux。
(3)必須有塊開發板(arm9以上),有條件可參加培訓(進步快,能認識些朋友)。
主攻書籍:毛德操的《嵌入式系統》及其他arm9手冊與arm匯編指令等。

4、深入學習:
A、數字圖像壓縮技術:主要是應掌握MPEG、mp3等編解碼演算法和技術。
B、通信協議及編程技術:TCP/IP協議、802.11,Bluetooth,GPRS、GSM、CDMA等。

2010-8-21 16:46 回復
122.90.173.* 2樓

C、網路與信息安全技術:如加密技術,數字證書CA等。
D、DSP技術:Digital Signal Process,DSP處理器通過硬體實現數字信號處理演算法。
說明:太多細節未說明,可根據實際情況調整。重點在於1、3,不必完全按照順序作。對於學習c++,理由是c++不只是一種語言,一種工具,她還是一種藝術,一種文化,一種哲學理念、但不是拿來炫耀得東西。對於linux內核,學習編程,讀一些優秀代碼也是有必要的。
注意: 要學會舉一反多,有強大的基礎,很多東西簡單看看就能會。想成為合格的程序員,前提是必須熟練至少一種編程語言,並具有良好的邏輯思維。一定要理論結合實踐。
不要一味鑽研技術,雖然擠出時間是很難做到的,但還是要留點餘地去完善其他的愛好,比如宇宙,素描、機械、管理,心理學、游戲、科幻電影。還有一些不願意做但必須要做的!
技術是通過編程編程在編程編出來的。永遠不要夢想一步登天,不要做浮躁的人,不要覺得路途漫上。而是要編程編程在編程,完了在編程,在編程!等機會來了在創業(不要相信有奇跡發生,盲目創業很難成功,即便成功了發展空間也不一定很大)。

嵌入式書籍推薦
Linux基礎
1、《Linux與Unix Shell 編程指南》
C語言基礎
1、《C Primer Plus,5th Edition》【美】Stephen Prata著
2、《The C Programming Language, 2nd Edition》【美】Brian W. Kernighan David M. Rithie(K & R)著
3、《Advanced Programming in the UNIX Environment,2nd Edition》(APUE)
4、《嵌入式Linux應用程序開發詳解》
Linux內核
1、《深入理解Linux內核》(第三版)
2、《Linux內核源代碼情景分析》毛德操 胡希明著
研發方向
1、《UNIX Network Programming》(UNP)
2、《TCP/IP詳解》
3、《Linux內核編程》
4、《Linux設備驅動開發》(LDD)
5、《Linux高級程序設計》 楊宗德著
硬體基礎
1、《ARM體系結構與編程》杜春雷著
2、S3C2410 Datasheet
英語基礎
1、《計算機與通信專業英語》
系統教程
1、《嵌入式系統――體系結構、編程與設計》
2、《嵌入式系統――採用公開源代碼和StrongARM/Xscale處理器》毛德操 胡希明著
3、《Building Embedded Linux Systems》
4、《嵌入式ARM系統原理與實例開發》 楊宗德著
理論基礎
1、《演算法導論》
2、《數據結構(C語言版)》
3、《計算機組織與體系結構?性能分析》
4、《深入理解計算機系統》【美】Randal E. Bryant David O''Hallaron著
5、《操作系統:精髓與設計原理》
6、《編譯原理》
7、《數據通信與計算機網路》
8、《數據壓縮原理與應用》

C語言書籍推薦
1. The C programming language 《C程序設計語言》
2. Pointers on C 《C和指針》
3. C traps and pitfalls 《C陷阱與缺陷》
4. Expert C Lanuage 《專家C編程》
5. Writing Clean Code -----Microsoft Techiniques for Developing Bug-free C Programs
《編程精粹--Microsoft 編寫優質無錯C程序秘訣》
6. Programming Embedded Systems in C and C++ 《嵌入式系統編程》
7.《C語言嵌入式系統編程修煉》
8.《高質量C++/C編程指南》林銳
盡可能多的編碼,要學好C,不能只注重C本身。演算法,架構方式等都很重要。

這里很多書其實是推薦而已,不必太在意,關鍵還是基礎,才是重中之重!!!

4. arm linux 應用程序 如何內嵌匯編

在linux源代碼中會有一部分c語言與匯編語言相交融的部分。
其中linux中匯編語言採用的不是我們通用的intel的匯編語言,而是採用的是AT&T格式的匯
編語言,它們之間有一些差別:
1
目標與源的方向不大一樣
mov
ax,
bx
mov
%bx,
%ax
2
AT&T寄存器前要加入%
ax
%ax
3
AT&T立即數前面要加上$
add
ax,
4
add
%ax,$4
4
對於訪問指令的操作數大小
intel的格式是在操作數前加上BYTE
PTR、DWORD
PTR等等
AT&T格式:在操作數後面加上b、l、w等
MOV
AL,
BYTE
PTR
FOO(intel)
movb
FOO,
%al
(AT&T)
5
間接定址:
SECTION:[BASE+INDEX*SCALE+DISP]
Section:disp(base,
index,
scale)
C語言中插入匯編代碼比純粹的匯編要難,因為要設計到「如何分配使用寄存器、怎樣與C語
言中變數相結合」
下面「=」代表只讀,「+」代表讀寫
每個輸出部分均以=開始
比如我想定義一個char型的變數,放入ax中
register
char
_temp
asm
("ax");
register
char
_temp
__asm__
("ax");
以上兩種方式均正確
在這里我們通常看到普通的寄存器前面有兩個%,代表下面的意思:第一寄存器前要有一個%
第二對於一個模板前要加入一個%
下面以一個在內核中常見的目的為了實現原子操作的一個函數為例子atomic_add來介紹
static
__inline__
void
atomic_add(int
i,
atomic_t
*v)
{
__asm__
__volatile__(
LOCK
"addl
%1,
%0"
:"=m"(v->counter)
:"ir"(i),
"m"(v->counter)
);
}
ir代表一個寄存器中的直接操作數
首先一個頭部:__asm__
__volatile__();
asm();
__asm__();告訴編譯器裡面是匯編語言
:第一個冒號是輸出部分:第二個冒號是輸入部分
其實還有第三個冒號:代表著損壞部分
asm("匯編語句"
:輸出部分
:輸入部分
:損壞部分)
%0、%1
等等代表著一種模板操作數,其中數字到幾取決於cpu寄存器數量
"m",
"v",
"o"
--內存單元
"r"
任意寄存器
"q"
表示eax、ebx、ecx、edx之一
"i",
"h"
表示立即數
"a",
"b",
"c",
"d"表示eax、ebx、ecx、edx
關鍵字LOCK表示在執行的時候把系統匯流排鎖住,不讓其他
cpu干擾。

5. 如何在c語言中嵌入匯編語言

vc6.0中使用__asm關鍵字。。vs中需要開啟此功能。。

在linux中, gcc/g++中 使用asm關鍵字來加入

6. 如何在64位的linux系統上使用匯編和C語言混合編程

C51與匯編語言混合編程(1).C51語言中調用匯編語言程序1、在文件中選中FILEGROUP和C51程序原文件,在配置文件選項中激活「i」產生匯編(SRC)文件,「編譯(SRC)文件」和「創建工程(目標)時包含「三個選項。2、根據選擇的編譯模式,把相應的庫文件(如SMALL模式,庫文件為KEIL\C51\LIB\C51S.LIB)加入到工程中。3、在C51語言中必須聲明需要調用的函數為外部函數。externvoidDELAY(void);4、在匯編語言程序中必須聲明被調用子程序為公共子程序,在被調用的文件中還需要聲明此文件是新定位的。PUBLICDELAY,實例如下:#include"reg51.h"externvoidDELAY(void);externvoidDEL(void);voidmain(void){P1=0x00;DELAY();DEL();P!=0xff;}匯編語言文件:PUBLICDELAY,DELAY:MOVR2,#3HDJNZR2,$RETDEL:MOVR3,#3HDJNZR3,$RETEND(2)、C51語言中嵌入匯編程序:在C51語言中嵌套使用匯編語言程序要注意以下幾個問題:1、在文件中選中FILEGROUP和C51程序原文件,在配置文件選項中激活「i」產生匯編(SRC)文件,「編譯(SRC)文件」和「創建工程(目標)時包含「三個選項。2、根據選擇的編譯模式,把相應的庫文件(如SMALL模式,庫文件為KEIL\C51\LIB\C51S.LIB)加入到工程中。3、用#pragmaasm.和#pragmaendasm語句包含嵌入的匯編語言程序。實例如下:#include"reg51.h"voiddelay(void);voidmain(void){voiddelay(void);P1=0x00;#pragmaasmMOVR3,#08HDINZR3,$#pragmaendasmP1=0xff;}voiddelay(void){#pragmaasmMOVR4,#08HDJNZR4,$#pragmaendasm}

7. 如何在64位的Linux系統上使用匯編和C語言混合編程

linux平台上的匯編語言風格叫做at&t風格,你可以搜索一下at&t內聯匯編規則。
一般是asm("") 這樣引用內聯匯編

8. 如何在linux下c++程序里嵌入匯編語句

gcc/g++嵌入的是AT&T匯編,語句用雙引號括起來,每句以\n\r結尾!
我只寫一段示例,剩下的你照做可以了:
WORD lookKbits(BYTE k)
{
_asm {
「movb k,%%dl\\n\\r」
"movb $16,%%cl\\n\\r"
"sub %%dl,%%cl\\n\\r"
"movl [wordval],%%eax\\n\\r"
"shrl %%cl,%%eax\\n\\r"
}
}

9. 在c語言(C++或G++)中如何嵌入匯編

今天有點時間,重新改下了下,為避免因編譯器和平台實現而出現的問題,我寫了三個版本,分別是windows下vc6.0,windows下mingw和cygwin和linux下的gcc/g++。

vc6.0:

#include <stdio.h>

const char* input = "%d";

const char* output = "%d\n";

int n;

int main()

{

__asm

{

lea eax, n

push eax

push input
loopx:

call scanf

cmp eax, 1

jne end

mov ecx, n

jecxz end

dec ecx

push ecx

push output

call printf

add esp, 8

jmp loopx
end:

add esp, 8

}

return 0;

}

mingw/cygwin:

#include <stdio.h>

const char* input = "%d";

const char* output = "%d\n";

int n;

int main()

{

__asm__

(

"loop: \n"

"pushl $_n \n"

"pushl _input \n"

"call _scanf \n"

"addl $8, %esp \n"

"cmpl $1, %eax \n"

"jne end \n"

"movl _n, %ecx \n"

"jecxz end \n"

"decl %ecx \n"

"pushl %ecx \n"

"pushl _output \n"

"call _printf \n"

"addl $8, %esp \n"

"jmp loop \n"

"end:"

);

return 0;

}

linux gcc/g++:

#include <stdio.h>

const char* input = "%d";
const char* output = "%d\n";
int n;

int main()
{
__asm__
(
"pushl $n \n"
"pushl input \n"
"loop: \n"
"call scanf \n"
"cmp $1, %eax \n"
"jne end \n"
"movl n, %ecx \n"
"jecxz end \n"
"decl %ecx \n"
"pushl %ecx \n"
"pushl output \n"
"call printf \n"
"addl $8, %esp \n"
"jmp loop \n"
"end: \n"
"addl $8, %esp \n");

return 0;
}

10. 如何在64位的Linux系統上使用匯編和C語言混合編程 第4頁

(1) 參數個數少於7個:
f (a, b, c, d, e, f);
a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%r8, f->%r9
g (a, b)
a->%rdi, b->%rsi
有趣的是, 實際上將參數放入寄存器的語句是從右到左處理參數表的, 這點與32位的時候一致.
CODE
2) 參數個數大於 7 個的時候
H(a, b, c, d, e, f, g);
a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%rax
g->8(%esp)
f->(%esp)
call H
易失寄存器:
%rax, %rcx, %rdx, %rsi, %rdi, %r8, %r9 為易失寄存器, 被調用者不必恢復它們的值。
顯然,這里出現的寄存器大多用於參數傳遞了, 值被改掉也無妨。而 %rax, %rdx 常用於
數值計算, %rcx 常用於循環計數,它們的值是經常改變的。其它的寄存器為非易失的,也
就是 rbp, rbx, rsp, r10~r15 的值如果在匯編模塊中被改變了,在退出該模塊時,必須將
其恢復。
教訓:
用匯編寫模塊, 然後與 c 整合, 一定要搞清楚編譯器的行為, 特別是參數傳遞的方式. 此外, 我現在比較擔心的一點是, 將來如果要把程序移植 到 WIN/VC 環境怎麼辦? 以前我用cygwin的gcc來處理匯編模塊, 用vc來處理c模塊, 只需要很少改動. 現在的問題是, 如果VC用 不同的參數傳遞方式, 那我不就麻煩了?

熱點內容
yy圖片文件夾 發布:2025-01-15 08:01:00 瀏覽:841
可緩存影視 發布:2025-01-15 07:42:50 瀏覽:799
php函數默認值 發布:2025-01-15 07:34:31 瀏覽:238
編譯應用後apk無法打開 發布:2025-01-15 07:33:45 瀏覽:438
lc腳本編輯器 發布:2025-01-15 07:18:59 瀏覽:529
追劇腳本 發布:2025-01-15 07:00:39 瀏覽:446
c語言字元串庫函數 發布:2025-01-15 06:54:49 瀏覽:526
c語言的工作 發布:2025-01-15 06:50:50 瀏覽:522
口語交際訪問 發布:2025-01-15 06:44:13 瀏覽:329
編程少兒學習 發布:2025-01-15 06:39:03 瀏覽:504