首页 未命名正文

linux编程_ARM汇编与C夹杂编程

云返利网 未命名 2020-05-26 09:08:41 18 0

GNU内联汇编

内联汇编即在C中直接使用汇编语句举行编程,使程序可以在C程序中实现C语言不能完成的一些事情,例如,在下面几种情形中必须使用内联汇编或嵌入型汇编

  1. 程序中使用饱和算术运算(Saturating Arithmetic)
  2. 程序需要对协处理器举行操作
  3. 在C程序中完成对程序状态寄存器的操作
__asm__ __volatile__("asm code":output:input:changed registers);

Note:

  1. 使用__asm____volatile__示意编译器将不检查后面的内容,而是直接交给汇编器。
  2. 若是希望变压器你优化,__volatile__可以不加
  3. 没有asm code也不能省略""
  4. 没有前面的和中心的部门,不可以响应的省略:
  5. 没有changed 部门,必须响应的省略:
  6. 最后的;不能省略,对于C语言来说这是一条语句
  7. 汇编代码必须放在一个字符串内,且字符串中心不能直接按回车换行,可以写成多个字符串,注重中心不能有任何符号,这样就会将两个字符串合并为一个
  8. 指令之间必须要换行,还可以使用\t使指令在汇编中保持整齐

asm code

"mov r0, r0\n\t"
"mov r1,r1\n\t"
"mov r2,r2"

output(asm->C)

:"constraint" (variable)

"constraint"用于界说variable的存放位置:
r示意使用任何可用的寄存器
m示意使用变量的内存地址
+可读可写
=只写
&示意该输出操作数不能使用输入部门使用过的寄存器,只能用"+&""=&"的方式使用

input(C->asm)

:"constraint" (variable/immediate)

"constraint"用于界说variable的存放位置:
r示意使用任何可用的寄存器(立刻数和变量都可以)
m示意使用变量的内存地址
i示意使用立刻数

例子

int a=100,b=200;
int result;
__asm__ __volatile__(
    "mov %0,%3\n\t"             //%0是一个占位符,示意result,之后的类推
    "ldr r0,%1\n\t"
    "ldr r1,%2\n\t"
    "str r0,%2\n\t"
    "str %1,%1\n\t"
    :"=r"(result),"+m"(a),"+m"(b)   
    :"i"(123)
);

ATPCS

  1. 子程序间通过寄存器R4~R11来通报参数,若是参数多于四个,则多出的部门用客栈通报,被挪用的子程序在返回前无须恢复寄存器R0~R3的内容
  2. 在子程序中,使用寄存器R4~R11来保留局部变量,若是在子程序中使用到了R4~R11中的某些寄存器,子程序进入时必须保留这些寄存器的值,在返回前必须恢复这些寄存器的值;对于子程序中没有用到的寄存器则不必举行这些操作,在Thumb程序中,通常只能使用寄存器R4~R7来保留局部变量
  3. R12用作子程序间scrtach寄存器(用于保留SP,在函数返回时使用该寄存器出栈),记作ip
  4. R13用作数据栈指针,记作sp
  5. R14用作毗邻寄存器,记作lr
  6. R15记作程序寄存器,记作pc

相互挪用

C挪用汇编

//.c
#include <stdio.h>
extern void strcopy(char* des, const char* src);
int main(){
    const char* srcstr = "src string";
    char desstr[]="des string";
    strcopy(desstr, srcstr);
    return 0;
}
;.asm
.global strcopy
strcopy:                ;R0指向目的字符串
                        ;R1指向源字符串
    LDRB R2, [R1], #1   ;加载字节并更新源字符串指针地址
    STRB R2, [R0], #1   ;存储季节并更新目的字符串指针地址
    CMP  R2, #0         ;判断是否为字符串末端
    BNE strcopy         ;若是不是,程序跳转到strcopy继续循环
    MOV pc, ir          ;程序返回

汇编挪用C

//.c
int fcn(int a, int b , int c, int d, int e){
    return a+b+c+d+e;
}
;.asm
;假设程序进入f时,R0中的值为i
;int f(int i){return fcn(i, 2*i, 3*i, 4*i, 5*i);}
.text
.global _start
_start:
    STR lr, [sp, #-4]! ;保留返回地址lr
    ADD R1, R0, R0      ;盘算2*i(第2个参数)
    ADD R2, R1, R0      ;盘算3*i(第3个参数)
    ADD R3, R1, R2      ;盘算5*i
    STR R3, [SP, #-4]! ;第5个参数通过客栈通报
    ADD R3, R1, R1      ;盘算4*i(第4个参数)
    BL fcn              ;挪用C程序
    ADD sp, sp, #4 ;从客栈中删除第五个参数
    .end

【关于云返利网】

云返利网是阿里云、腾讯云、华为云产品推广返利平台,在各个品牌云产品官网优惠活动之外,云返利网还提供返利。您可以无门槛获得阿里云、华为云、腾讯云所有产品返利,在官网下单后就可以领取,无论是自己用、公司用还是帮客户采购,您个人都可以获得返利。云返利网的目标是让返利更多、更快、更简单!详情咨询13121395187(微信同号)