我正在用 atmel 编写 AVR 程序集,但“调用”指令不起作用

Posted

技术标签:

【中文标题】我正在用 atmel 编写 AVR 程序集,但“调用”指令不起作用【英文标题】:I'm writing AVR assembly in atmel, but "call" instruction doesn't work 【发布时间】:2016-10-07 18:52:03 【问题描述】:

我正在使用 Atmel Studio 6.2 为 Atmega328p 编写一些汇编代码。

但是,当我使用模拟器并逐步执行程序时,子程序的call 指令不起作用。它完全忽略了call 指令并继续下一行。

为了测试call指令,我写了一个简单的程序,如下所示:

.include "m328pdef.inc"

ldi R16, 11
call hello_world
mov R1, R0
nop

hello_world:
    mov R0, R16
    ret

但即使这样也行不通!它只是继续执行mov R1, R0。 可能是什么原因?当call 不起作用时真是太烦人了!

【问题讨论】:

在调试器中,你是使用命令“step”还是命令“next”? 我之所以问,是因为通常调试器既有一个执行处理器执行的下一条指令的命令,又有一个执行到程序中下一行代码的命令(例如,在 hello_world 完成之后执行)。 哦哦!!!我只是傻!!是的我很傻!!!当它来电时,我应该点击“进入”!!!!!!!现在可以了 T.T 我不得不因为愚蠢而把头撞到墙上!!!!非常感谢:) :) :) 所以在那个“愚蠢的简单程序”中,您可以在hello_world: 中执行ldi R16,5 并查看R16call 之后是否发生了变化。 【参考方案1】:
.include "m328pdef.inc"
ldi r16,11 
ldi r17,0
ldi r18,1
rcall hello_world
mov r16,r17
nop

hello world:
mov r16,r18
ret

我用的是r16、r17和r18,因为它的通用寄存器,只用于调试。 这是一步一步的解释: 1. 加载立即数“11”到r16 2. 加载立即数“0”到r17 3. 加载立即数“1”到r18 4.调用hello_world标签。将地址压入堆栈 5.将值从r18(1)移动到r16,所以r16的值为1 6. ret,弹出地址,然后返回 7.将值从r17(0)移动到r16,r16值为0

如果您一次运行程序而不是逐步运行程序,您将不会知道其中的区别。 希望对您有所帮助

【讨论】:

【参考方案2】:

你必须定义堆栈 http://www.avr-tutorials.com/assembly/writing-assembly-subroutines-avr-microcontroller

;Initialize the microcontroller stack pointer
                LDI    R16, low(RAMEND)
                OUT    SPL, R16
                LDI    R16, high(RAMEND)
                OUT    SPH, R16

【讨论】:

以上是关于我正在用 atmel 编写 AVR 程序集,但“调用”指令不起作用的主要内容,如果未能解决你的问题,请参考以下文章

ATMEL AVR STUDIO 程序

在 atmel studio7 中更改起始地址 .hex

工控硬件

在 Atmel AVR studio 中使用 ATMega2560 读取 RC PWM 信号

Linux / Windows Arduino IDE 上的 avr-gcc Atmel AVR 微控制器

Atmel AVR 汇编器时间戳计数器