在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+INDEXSCALE+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干扰。
硬件平台:FS2410开发平台:MDK35程序源码:GPFCON EQU 0x56000050 ;Port F control
GPFDAT EQU 0x56000054 ;Port F data
GPFUP EQU 0x56000058 ;Pull-up control F
AREA myarea, CODE
ENTRY LDR r0, =0x5500
LDR r1, = GPFCON
STR r0,[r1] LDR r0, = 0x0
LDR r1, =GPFUP
STR r0,[r1]
start_while
LDR r0, = 0x0
LDR r1, =GPFDAT
STR r0,[r1] LDR r0, =0xffffloop1
SUBS r0,r0, #1
BNE loop1 LDR r0, = 0xF0
LDR r1, =GPFDAT
STR r0,[r1] LDR r0, =0xffff
loop2
SUBS r0,r0, #1
BNE loop2 B start_whilestop
B stop
END
以上就是关于arm linux 应用程序 如何内嵌汇编全部的内容,包括:arm linux 应用程序 如何内嵌汇编、求 嵌入式ARM中 注明开发板型号 LED一盏灯亮,灭,中间设置延迟。c 或汇编、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)