首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

單片機 C 語言實現絕對地址定位:對應匯編 ORG 指令的多種方案

     編輯:C 語言問答

場景:在 ROM 0x2200 處放置常數 0x01

方案一:指標強制轉型 (最通用、可運行時動態決定地址)

#include <stdint.h>
#define ROM_ADDR 0x2200U

void write_rom_const(void) {
    volatile uint8_t *p = (volatile uint8_t *)ROM_ADDR;
    *p = 0x01;  // 寫入
    // uint8_t val = *p; // 讀取
}
  • 必須加 `volatile` 防止編譯器優化掉讀寫。
  • 適用於 RAM、外設寄存器、記憶體映射 IO、Bootloader 共享資料區。

方案二:編譯器屬性/段屬性 (靜態編譯期固定、進入映像檔)

GCC/Clang (屬性語法)

const uint8_t my_const __attribute__((section(".my_rom_section"))) = 0x01;
// 連結腳本 .ld 控制 .my_rom_section 載入地址
// .my_rom_section 0x2200 : { *(.my_rom_section) }

Keil C51 / ARM (關鍵字/編譯指令)


// C51
unsigned char code my_const _at_ 0x2200 = 0x01; // code 關鍵字放入程式碼區(ROM)
// ARM (ARMCC/ARMCLANG)
__attribute__((section(".ARM.__at_0x2200"))) const uint8_t my_const = 0x01;
// 或 #pragma arm section rodata = "MY_CONST"

IAR (ICC)


#pragma location=0x2200
__root const uint8_t my_const = 0x01;

方案三:連結器腳本 / 散載文件 統一管理 (專案級推薦)

將所有需固定地址的資料/代碼集中定義在自定義段,由連結腳本 (GCC `.ld`)、散載文件 (Keil `.sct` / IAR `.icf`) 統一指定載入地址 (VMA/LMA),避免硬編碼地址散落業務代碼中。

方案四:啟動代碼 / Bootloader 協作

若需在應用程式啟動前初始化特定地址 (如向量表、配置字、加密金鑰),在啟動檔 (`startup.s` / `Reset_Handler` 前) 用匯編或 C 代碼 (`__low_level_init`) 完成,再跳轉主程式。

注意事項

  • 寫入 Flash/ROM 通常需解鎖、擦除扇區、編程、驗證,不能簡單視為 RAM 寫入。參考芯片手冊 Flash Controller 章節。
  • 記憶體保護單元 (MPU) / 信任區 (TrustZone) 可能禁止該地址訪問,需配置權限。
  • 跨專案複用時,地址衝突風險高,建議集中管理、文檔化、編譯期斷言檢查 (`_Static_assert`)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved