当前文档版本为 v0.5.0,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

内联汇编

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