# 第7章读后感
第7章介绍内嵌汇编的使用方法,内嵌汇编可以在C语言环境下通过汇编方式操作寄存器,对于特别重要和时间敏感的代码进行优化。思维导图如下。
# 实验验证
## 实验7-1:实现简单的memcpy()函数 、实验7-2:使用汇编符号名写内嵌汇编代码
代码:
```c
void s_memcpy(void *src, void * dst, int size)
{
asm volatile (
"li t2, 0 \n"
"l: lb t0, (%[src]) \n"
"sb t0, (%[dst]) \n"
"addi %[src], %[src], 1 \n"
"addi %[dst], %[dst], 1 \n"
"addi t2, t2, 1 \n"
"bltu t2, %[size], l \n"
/*输出部分*/
:[dst] "+r" (dst) , [src] "+r" (src)
/*输入部分*/
:[size] "r" (size)
/*破坏部分*/
:"memory", "t0", "t2"
);
}
```
仿真实验验证。
## 实验7-3:使用内嵌汇编代码完善memset()函数
代码:
```c
void _s_memset_16bytes(void *p, unsigned long val, int count)
{
int i = 0;
asm volatile (
"l2: sd %[val], (%[p])\n"
"sd %[val], 8(%[p])\n"
"addi %[p], %[p], 16 \n"
"addi %
, %, 1 \n"
"blt %, %[count], l2"
: [p] "+r" (p),"+r" (i)
: [val]"r" (val), [count]"r" (count)
: "memory"
);
}
```
## 实验7-4:使用内嵌汇编代码与宏的结合
代码:
```c
#define MY_OPS(ops, asm_ops) \
void _asm_##ops(unsigned long mask, void *p) \
{ \
unsigned long tmp = 0; \
asm volatile ( \
"ld %[tmp], (%[p])\n" \
" "#asm_ops" %[tmp], %[tmp], %[mask]\n" \
"sd %[tmp], (%[p])\n" \
: [p] "+r"(p), [tmp]"+r" (tmp) \
: [mask]"r" (mask) \
: "memory" \
); \
}
MY_OPS(or, or)
MY_OPS(xor, xor)
MY_OPS(and, and)
MY_OPS(sub, sub)
```
仿真实验验证。
或操作验证
异或操作验证
与操作验证
减法操作验证
## 实验7-5:实现读和写系统寄存器的宏
代码:
```c
/*
* 在带参数的宏,#号作为一个预处理运算符,
* 可以把记号转换成字符串
*
* 下面这句话会在预编译阶段变成:
*asm volatile("csrr %0, " "reg" : "=r" (__val)); __val; });
*/
#define read_csr(csr) \
({ \
register unsigned long __v; \
__asm__ __volatile__ ("csrr %0, " #csr \
: "=r" (__v) : \
: "memory"); \
__v; \
})
#define write_csr(val, csr) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrw " #csr ", %0" \
: : "rK" (__v) \
: "memory"); \
})
```
## 实验7-6:goto模板的内嵌汇编代码
代码:
```c
int test_asm_goto(int a)
{
asm goto(
"addi %[a], %[a], -1 \n"
"beqz %[a], %[label] \n"
:/*输出部分是空的*/
:[a] "r"(a)
:"memory"
:label
);
return 0;
label:
return 1;
}
```
仿真实验验证。