内联汇编¶
内联汇编使用关键字__asm。
1 2 3 | __asm{ //汇编指令 } |
内联汇编中仅支持汇编指令,不支持汇编控制语句,无法在汇编中定义变量。
汇编指令之间必须使用分号;分割,仅仅换行是不行的。
注意
C语言定义的名字为a/A的元素在内联汇编中无法访问,因为其与累加器同名,应避免这种情况。
内联汇编访问data变量¶
data变量的名字在内联汇编中可以直接使用,其代表的即为变量的地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | char x = 12; uint16_t y; int32_t z; __asm{ //y = x mov A, x; mov y, A; and A, #0x80; sz A; mov A, #0xff; mov y + 1, A; //z = y + 5 mov A, y; add A, #5; mov z, A; mov A, #0; addc A, y + 1; mov z + 1, A; mov A, #0; addc A, y + 2; mov z + 2, A; mov A, #0; addc A, y + 3; mov z + 3, A; } |
内联汇编访问data数组¶
data数组的名字在内联汇编中可以直接使用,其代表的即为数组的首地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | uint8_t arr[10];
uint16_t sum = 0;
__asm{
//循环为数组赋值
mov A, #arr;
mov IADR, A;
mov A, 0;
loop_w:
mov IDAT, A;
inc IADR;
inc A;
se A, #10;
jmp loop_w;
//数组直接访问
mov A, #123;
mov arr + 4, A;
//数组求和
mov A, #arr;
mov IADR, A;
mov A, #10;
mov A, IDAT;
add sum, A;
mov A, #0;
addc sum + 1, A;
inc IADR;
dsz A;
jmp $ - 6;
}
|
内联汇编访问code数组¶
由于code数组有两种存储方式,因此,访问时也要分两种。
单字节元素code数组¶
单字节元素code数组存储为跳转表形式,因此内联汇编中要以调用子程序的方式来访问,调用子程序前需将下标值放到累加器A中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | //arr:
__code uint8_t arr[10] = { //add PCL, A
0, //ret #0
1, //ret #1
2, //ret #2
3, //ret #3
4, //ret #4
5, //ret #5
6, //ret #6
7, //ret #7
8, //ret #8
9 //ret #9
};
uint8_t i = 0;
uint16_t sum = 0;
__asm{
//数组求和
mov A, i;
call arr;
add sum, A;
mov A, #0;
addc sum + 1, A;
inc i;
mov A, i;
se A, #10;
jmp $ - 8;
}
|
多字节元素code数组¶
多字节元素code数组直接以数据形式存储在code区,因此直接使用movc指令即可访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | __code uint16_t arr[10] = { //arr:
0, //dw 0
1, //dw 1
2, //dw 2
3, //dw 3
4, //dw 4
5, //dw 5
6, //dw 6
7, //dw 7
8, //dw 8
9 //dw 9
};
uint8_t n = 10;
uint16_t sum = 0;
__asm{
//数组求和
mov A, #arr & 0xff;
mov IAPADRL, A;
mov A, #arr >> 8;
mov IAPADRH, A;
movc A;
add sum, A;
mov A, IAPDATH;
addc sum + 1, A;
isnz IAPADRL;
inc IAPADRH;
dsz n;
jmp $ - 7;
}
|