You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVR汇编:如何从程序存储器加载空终止字符串入栈并反转写入数据存储器?

AVR汇编:加载Flash字符串压栈并反转写入SRAM

1. 从程序存储器加载空终止字符串并压栈

AVR的程序存储器(Flash)需通过LPM指令读取。空终止字符串以0x00结尾,我们逐个加载字节,非终止符则压入栈,同时记录字符串长度(方便后续反转写入)。

代码片段

; 在Flash中定义空终止字符串
.cseg
my_str: .db "Hello World", 0x00

; 寄存器定义
.def str_len = r17  ; 存储字符串长度
.def temp_byte = r16 ; 临时存储读取的字节

; 初始化Z寄存器指向Flash字符串起始地址
ldi ZH, high(my_str << 1)  ; Flash是16位字寻址,字节地址需左移1位
ldi ZL, low(my_str << 1)
clr str_len                ; 初始化长度计数器

load_and_push:
lpm temp_byte, Z+          ; 读Flash字节到temp_byte,Z自增指向下一字节
cpi temp_byte, 0x00        ; 检查是否为空终止符
breq push_done             ; 是则退出压栈循环
push temp_byte             ; 非终止符压入栈
inc str_len                ; 长度计数器+1
rjmp load_and_push

push_done:

2. 将反转后的字符串写入数据存储器(SRAM)

栈是后进先出结构,弹出的字节即为原字符串的逆序。我们用X寄存器指向SRAM目标地址,按长度计数器循环弹出并写入,最后添加空终止符。

完整续接代码

; 初始化X寄存器指向SRAM目标起始地址(示例:0x0100)
ldi XH, high(0x0100)
ldi XL, low(0x0100)

reverse_and_store:
cpi str_len, 0x00          ; 检查是否已处理完所有字符
breq store_done
pop temp_byte              ; 弹出栈顶字节(逆序字符)
st X+, temp_byte           ; 写入SRAM,X自增指向下一地址
dec str_len                ; 长度计数器-1
rjmp reverse_and_store

store_done:
st X, 0x00                 ; 在反转字符串末尾添加空终止符

; 程序终止(原地循环)
end_loop:
rjmp end_loop

关键细节说明

  • Flash地址处理:AVR Flash采用16位字寻址,而LPM按字节读取,因此字符串的字节地址需左移1位转换为字地址,才能让Z寄存器正确指向目标字节。
  • 栈操作:PUSH指令将寄存器值存入栈指针(SP)指向的SRAM地址,随后SP减1;POP指令从SP+1地址读取值到寄存器,随后SP加1,天然适配逆序需求。
  • SRAM地址选择:需确保目标地址在当前AVR芯片的SRAM范围内,例如ATmega328P的SRAM范围是0x0060到0x08FF,避免越界。

内容的提问来源于stack exchange,提问作者Trung Thành Đỗ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:53:32