TI的C28x CPU指令集学习(二)

Direct Addressing Mode(直接寻址模式)


1. 基本概念

Direct Addressing Mode(直接寻址模式)是一种固定页寄存器 + 偏移量的寻址方式。
在这种模式下,指令并不会直接给出完整的 16 位或 32 位地址,而是由以下两部分组成:

  • DP 寄存器 (Data Page Pointer):一个 16 位的数据页指针寄存器,存储基准页地址。
  • Offset(偏移量):指令中给出的 6 位或 7 位偏移字段

最终的有效地址由 DP 与 Offset 拼接得到。


2. 有效地址计算方式

如果 DP 是 16 位,而 Offset 是 6/7 位,那么有效地址为:

Effective Address = (DP << 6 or 7) | Offset

也可以理解为:

有效地址 = 数据页基地址 + 偏移量

例如:

  • 假设 DP = 0x2000
  • 偏移量 = 0x3A(6 位)
  • 那么有效地址 = 0x2000 | 0x3A = 0x203A

3. 使用场景

Direct Addressing Mode 特别适用于访问固定地址的数据结构,例如:

  • 片上外设寄存器
    比如 UART、SPI、I2C 等硬件寄存器
  • 全局变量 / 静态变量
  • C/C++ 静态内存区

因为这些数据的起始地址通常是固定的,所以只需要把 DP 寄存器指向对应的页基地址,再通过指令中的 Offset 获取最终地址即可。


4. 优势

  • 代码更精简:只需要在指令里存放较短的偏移量,而不是完整的地址。
  • 访问速度快:避免频繁加载长地址。
  • 适合固定数据结构:例如外设寄存器、常量表、全局变量等。


好的😊,我们结合 Direct Addressing Mode(直接寻址模式)DP寄存器,对这句话逐层分析,帮助你彻底理解它在硬件和编译器层面上的意义。

这句话是:

“这种寻址方式可用于访问固定地址数据结构,例如外围寄存器和 C/C++ 中的全局或静态变量。”


1. 背景:Direct Addressing Mode + DP

Direct Addressing Mode 下:

  • 指令只给出 页内偏移量 (Offset),而不是完整的 16 位地址。
  • 高位页号由 DP(Data Page Pointer)寄存器提供。
  • 最终有效地址 = DP高10位 + Offset低6位

这种寻址方式非常适合访问一块固定地址的内存区域,因为:

  • 页号(DP)一般不变
  • 只改 Offset → 就能快速访问该页内的不同数据

2. “固定地址数据结构”是什么意思

固定地址数据结构就是那些起始地址不会动态变化的存储区域,包括:

(1) 外围寄存器(Peripheral Registers)

  • MCU / DSP 上的外设寄存器(UART、SPI、I2C、ADC、Timer等)一般放在固定的内存映射地址

  • 例如:

    外设 起始地址 大小
    UART 0x2000 64B
    SPI 0x2040 64B
    I2C 0x2080 64B
  • 如果我们把 DP=0x2000,那么:

    • UART_TX 寄存器 → DP + 0x00
    • UART_RX 寄存器 → DP + 0x04
    • UART_SR 状态寄存器 → DP + 0x08
  • 只需修改 Offset,不需要每次写完整 16 位地址。


(2) C/C++ 中的全局变量 (Global Variables)

在 C/C++ 编译时,全局变量一般会被放在一个固定的内存段(例如 .data.bss 段)。
这些段的基地址是确定的,编译器可以让 DP 指向全局变量所在的页:

int g_count = 0;  // 全局变量

假设编译器把 g_count 放在内存 0x3002

  • 如果 DP = 0x3000
  • Offset = 0x02
  • CPU 访问 g_count 时,只需要写一个 6 位 Offset,而不用写完整 16 位地址。

(3) 静态变量 (Static Variables)

void foo() {
    static int s_data = 5;
}
  • 静态变量 s_data 也放在固定的 .data.bss 段,不会像局部变量那样放在栈上。
  • 编译器可以同样使用 DP + Offset 的方式访问。

3. 为什么 Direct Addressing Mode 特别适合这种情况

特点 普通寻址 Direct Addressing Mode
指令中的地址 16 位完整地址 只需 6 位 Offset
DP寄存器 不用 保存页基地址
访问效率
代码大小
应用场景 动态内存、堆栈 外设寄存器、全局变量、静态变量

由于外设寄存器、全局变量、静态变量起始地址是固定的,DP 只需要配置一次,高效又节省指令空间。


4. 举个例子

假设有一个 UART 外设:

#define UART_DR  (*(volatile unsigned char*)0x2002)
#define UART_SR  (*(volatile unsigned char*)0x2004)

如果我们设置:

DP = 0x2000
Offset(UART_DR) = 0x02
Offset(UART_SR) = 0x04

那么:

  • UART_DR → 有效地址 = DP + 0x02 = 0x2002
  • UART_SR → 有效地址 = DP + 0x04 = 0x2004
  • 不需要每次写完整 16 位地址。

5. 总结

这句话的核心意思是:

Direct Addressing Mode 通过 DP寄存器 + Offset 拼接完整地址,
非常适合访问那些起始地址固定的内存区域:

  • 外围寄存器(外设控制寄存器)
  • 全局变量
  • 静态变量

因为:

  • 页号固定 → DP 只需初始化一次
  • 偏移量小 → 指令只需写 Offset,节省 ROM
  • 效率高 → 访问速度快

如果你想,我可以给你画一张图,展示:

  • 64KB 内存划分
  • 外设寄存器所在的页
  • 全局变量所在的页
  • DP + Offset 如何快速定位到这些固定地址

我来用中文详细分析 Stack Addressing Mode(堆栈寻址模式) 这段话,结合 C28x DSP 的特性,逐句解释。


1. 基本概念

Stack Addressing Mode(堆栈寻址模式)是一种基于栈指针 SP (Stack Pointer) 的寻址方式,用于访问软件堆栈 (software stack) 上的数据。

SP (Stack Pointer)
是一个 16 位寄存器,用于指向软件栈的当前位置。


2. C28x 软件栈特点

文中提到的 C28x 是 TI C2000 DSP 内核,栈有几个特点:

(1) 软件栈在内存中是连续区域

  • 软件栈 (software stack) = 程序专用的一块内存空间。

  • 用于保存:

    • 函数返回地址
    • 局部变量
    • 寄存器现场
    • 中断上下文
  • 这块内存由 SP 寄存器管理。


(2) 栈从低地址向高地址增长

“The software stack grows from low to high memory on the C28x”

不同 CPU 架构,栈的增长方向不一样:

  • 大多数 MCU:栈从高地址向低地址增长(ARM、x86 等)。
  • C28x DSP栈从低地址向高地址增长

比如:

初始 SP = 0x2000
PUSH 一个 2 字节数据 → SP = 0x2002
再 PUSH 一个 2 字节数据 → SP = 0x2004

(3) SP 总是指向“下一个空闲位置”

“the stack pointer always points to the next empty location”

区别于某些 CPU(SP 指向栈顶数据),C28x 的 SP 始终指向栈内下一个可用空位,方便 PUSH/POP 操作。

例如:

  • 当前栈数据:

    [0x2000] = 0xAAAA
    [0x2002] = 0xBBBB
    [0x2004] = (空)
    
  • 此时 SP = 0x2004(指向下一个空位置)。


3. 指令中的 Offset 用法

“The instruction supplies a 6-bit offset field that is subtracted from the current stack pointer value for accessing data on the stack”

  • 指令会带一个 6 位 Offset,用于访问栈上已有数据。
  • CPU 会用:
有效地址 = SP - Offset

而不是 SP + Offset,因为 SP 指向“下一个空位”,想访问栈上的旧数据,必须往回退。

举例

假设:

  • SP = 0x2008
  • 指令中 Offset = 4

那么访问地址:

有效地址 = SP - 4 = 0x2008 - 0x0004 = 0x2004

4. PUSH / POP 操作

“the stack pointer can be post-incremented or pre-decremented when pushing and popping data from the stack”

(1) PUSH 操作(压栈)

  • 把数据存到栈顶
  • 先写数据,再 SP 增加
  • 叫做 post-increment(后增)
PUSH ACC

假设:

SP = 0x2000
PUSH 2 字节

过程:

[0x2000] = ACC
SP = SP + 2 → 0x2002

(2) POP 操作(出栈)

  • 从栈顶读取数据
  • 先 SP 减少,再读数据
  • 叫做 pre-decrement(先减)
POP ACC

假设:

SP = 0x2004
POP 2 字节

过程:

SP = SP - 2 → 0x2002
ACC = [0x2002]

5. 总结

概念 说明
SP (Stack Pointer) 16 位寄存器,指向栈中下一个空位置
软件栈 存储函数返回地址、局部变量、寄存器现场等
栈增长方向 C28x 从 低地址 → 高地址
SP 指向 下一个空闲位置
Offset 寻址 指令提供 6 位 Offset,SP - Offset 访问已有数据
PUSH 先写数据,SP 后增(post-increment)
POP SP 先减,后读数据(pre-decrement)

如果你想,我可以给你画一张 C28x 软件栈示意图,标出:

  • 栈的增长方向
  • SP 的指向
  • PUSH / POP 动作
  • Offset 访问方式

明白😊,我来详细分析 Register Addressing Mode(寄存器寻址模式)C28x DSP 架构中的含义、特点和应用场景。

这段话是:

“In this mode, another register can be the source or destination operand of an access.
This enables register-to-register operations in the C28x architecture.”

我们一步一步解析。


1. 什么是 Register Addressing Mode

寄存器寻址模式(Register Addressing Mode)是 C28x 指令系统中最直接最快速的一种寻址方式。

  • 指令操作数直接是寄存器,而不是内存地址。
  • 参与运算的两个操作数可以都在寄存器里。
  • 目标操作数(destination)也可以是寄存器。

2. 指令操作数的来源与去向

(1) Source Operand(源操作数)

  • 从一个寄存器中读取数据作为输入。
  • 例如:
ADD ACC, AR1

含义:

ACC = ACC + AR1

这里,AR1 作为源操作数。


(2) Destination Operand(目的操作数)

  • 运算结果可以直接写回某个寄存器。
  • 例如:
MOV AR2, ACC

含义:

AR2 = ACC

这里,AR2 作为目的操作数。


(3) Register-to-Register 操作

这句话:

“This enables register-to-register operations in the C28x architecture.”
意思是:
C28x 架构支持寄存器到寄存器之间的直接操作,无需访问内存。

例如:

MOV AR0, AR1

含义:

AR0 = AR1
  • 数据在寄存器间直接传递,速度最快。
  • 无需经过数据总线访问内存。

3. 与其他寻址模式的对比

寻址模式 操作数来源 是否需要访问内存 速度 常用场景
Register Addressing 直接寄存器 最快 寄存器之间的数据计算
Immediate Addressing 指令中写死的常量 常量计算
Direct Addressing DP + Offset 指向内存 中等 外设寄存器,全局变量
Indirect Addressing XARn 指向的内存 较慢 数组、表、缓冲区
Stack Addressing SP + Offset 指向栈 较慢 局部变量、函数调用

C28x 使用寄存器寻址模式时,完全绕过内存,速度最快,非常适合高频操作。


4. 常用寄存器类型

在 C28x 中,常见的寄存器有:

寄存器 位宽 用途
ACC 32 位 累加器,主要用于算术运算
P 32 位 乘法器结果寄存器
AR0~AR7 16 位 通用寄存器,可用于运算或索引
XAR0~XAR7 32 位 扩展地址寄存器,用于间接寻址
SP 16 位 栈指针
DP 16 位 数据页指针

寄存器寻址模式可以在这些寄存器之间直接操作数据,避免访问内存。


5. 示例

(1) 两寄存器相加

ADD AR0, AR1

含义:

AR0 = AR0 + AR1

(2) 把数据从累加器移到寄存器

MOV AR2, ACC

含义:

AR2 = ACC

(3) 从寄存器拷贝到寄存器

MOV AR3, AR7

含义:

AR3 = AR7

6. 总结

特性 说明
操作数位置 操作数直接在寄存器中
源寄存器 可直接用作输入
目的寄存器 运算结果可直接写回
效率 最快的寻址方式
应用 高频计算、寄存器间数据传递

C28x 使用寄存器寻址模式可以实现高速寄存器到寄存器运算,不需要访问内存,非常适合 DSP 高频运算场景。


如果你想,我可以给你画一张图,展示:

  • 两个寄存器之间直接操作数据
  • 和访问内存相比,寄存器寻址模式为什么速度更快

2377d17f-7843-4fd8-be65-efe5225e7e1a

posted @ 2025-09-01 15:31  江左子固  阅读(30)  评论(0)    收藏  举报