【发布时间】:2014-09-19 02:44:41
【问题描述】:
我正在尝试使用 AVR-gcc 在 AVR 程序集中编写一些条件跳转。根据AVR指令集手册,brxx指令接受一个操作数k,并跳转到PC+k+1。另外,根据http://www.avrbeginners.net/new/tutorials/jumps-calls-and-the-stack/ 的教程PDF,我应该可以使用PC 操作数像这样跳转:
brne PC+2
但是,当我编写这样的测试代码时:
#include <avr/io.h>
.section .text
.global main ; Note [5]
main:
sbi _SFR_IO_ADDR(DDRA), PA0
sbi _SFR_IO_ADDR(PORTA), PA0
ldi 16, 0xFF
cpi 16, 0xFF
breq PC + 2
cbi _SFR_IO_ADDR(PORTA), PA0
rjmp end
end:
rjmp end
我收到此错误:
avr-gcc -mmcu="atmega16" -DF_CPU="16000000UL" -O0 main.S -o main.o
/tmp/ccAa2ySf.o: In function `main':
(.text+0x8): undefined reference to `PC'
collect2: ld returned 1 exit status
make: *** [main.o] Error 1
显然 PC 没有在 AVR-libc 中定义。那我该怎么做这样的条件分支呢?谢谢!
更新 1
我发现了这个问题How can I jump relative to the PC using the gnu assembler for AVR?,发现gnu as 的语法是breq .+2。但是,我得到与该问题相同的错误。当我使用avr-objdump -d main.o 反汇编时,我确实得到了
74: 01 f0 breq .+0 ; 0x76
这与该问题的症状相同。我会尝试使用链接器脚本,但我没有这方面的经验。
更新 2
实际上我发现如果我在 breq 指令中使用偶数,比如breq .+2 或breq .+4,objdump 会显示正确的结果。但是,如果我使用奇数,它将变为breq .+0。谁能解释一下原因?
【问题讨论】:
标签: gcc assembly linker branch avr