在下面的代码中,我设置TRIS寄存器的第一个,然后是第二个,然后是第三个,最后是第四个。为什么生成的汇编代码…<<em>奇怪/em>吗?
要知道:编译代码的微控制器的数据存储器被分成几个银行。第6位和第7位进入status
寄存器的第5位和第6位,只有0-5位存储在操作码中。当访问位置0x86的TRIS
寄存器时,存储在操作码中的值因此是6
。
-
(134)^080
:这是转换为6
,这是TRIS
在该特定银行的地址。为什么编译器不直接写(6)
或(134)
?只是为了说明TRIS不在0号银行,还是有其他原因? -
+(0/8)
:0
表示位位置,8
表示该寄存器中的总位数。在我看来,这个表达式没有任何作用,因为结果总是一个分数,而不是一个整数。因此,它不参与地址计算。 -
(0)&7
:(0)
再次代表位位置,但是7
的二进制与服务的目的对我来说是完全不清楚的。 -
line
命令的作用是什么?
代码(从生成的*中提取)。文件)
;main.c: 9: TRISB |= 1;
bsf status, 5 ;RP0=1, select bank1
bcf status, 6 ;RP1=0, select bank1
bsf (134)^080h+(0/8),(0)&7 ;volatile
line 10
;main.c: 10: TRISB |= 2;
bsf (134)^080h+(1/8),(1)&7 ;volatile
line 11
;main.c: 11: TRISB |= 4;
bsf (134)^080h+(2/8),(2)&7 ;volatile
line 12
;main.c: 12: TRISB |= 8;
bsf (134)^080h+(3/8),(3)&7 ;volatile
line 13
标题>
不熟悉XC8编译器或PIC架构,我不能确切地说为什么编译器会发出(134)^080
,但它应该使阅读汇编更容易,因为它显示了预期的地址。如果它只是把6
放在那里,你必须回到程序集,寻找status
最后被修改的地方,以找出实际的地址是什么。
void emit_set_bit_insn(char const *addr, int bit) {
printf("bsf %s+(%d/8),(%d)&7n", addr, bit, bit);
}
现在考虑emit_set_bit_insn("var16", 10)
将输出什么:
bsf var16+(10/8),(10)&7
,汇编程序将其计算为:
bsf var16+1,2
设置var16
第二个字节的第2位,这与设置16位变量var16
的第10位是一样的。(好吧…假设字节顺序为小端序,这显然是XC8编译器遵循的约定。)
当然,编译器可以自己完成所有的算术运算,但不这样做会使编译器的代码更简单。无论哪种方式,汇编程序都将生成相同的机器码。
作为kirill建议line
指令不是一个汇编指令。它用于通知汇编程序C源代码中的哪一行与下面的指令相关联。汇编程序将使用这些信息来生成调试信息,调试器可以使用这些信息来显示程序中给定地址的相关源代码。
编译器根据特定的正则表达式生成汇编代码,然后将正确的值插入其中。具体的单词line
不是一个实际的汇编命令。