内联汇编¶
内联汇编使用关键字__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;
}
 |