在 C 中引用匯編語言定義的 .globl 變數

ARM的程式設計師敲著詩歌的夢發表於2020-04-04

緣起

在 Linux-0.11 中遇到了這種用法,所以想做個實驗以加深理解。

實驗程式碼

分為2個原始檔和1個Makefile.

a.s

.globl phone_num
.data
phone_num:
.word 0x1234
.word 0x5678

可以認為,phone_num是一個全域性變數,可以供其他檔案連結,phone_num的值是0x56781234.

b.c

#include <stdio.h>

extern unsigned int phone_num; //宣告a.s中的phone_num變數
int main(void)
{
    printf("phone = 0x%x\n", phone_num);
    printf("&phone_num = %p\n", &phone_num);
    return 0;
}

Makefile

TGT =main
C_SRC = $(wildcard *.c)
ASM_SRC = $(wildcard *.s)
OBJ =$(patsubst %.c,%.o,$(C_SRC))
OBJ +=$(patsubst %.s,%.o,$(ASM_SRC))
CC =gcc
$(TGT): $(OBJ)
    $(CC) -o $@ $^ 
clean:
    $(RM) $(TGT) *.o

編譯與執行

編譯後生成可執行檔案main
這裡寫圖片描述

執行main,結果如下:
這裡寫圖片描述

分析結果

可以看到,我們成功地在C程式中引用了a.s裡面定義的符號(或者說變數)phone_num.

注意
1. phone_num的地址是在連結後確定的。如果想檢視符號地址,可以用nm命令。

nm main

這裡寫圖片描述

  1. 識別符號 phone_num,在組合語言中代表一個記憶體地址;但是在C語言中,則表示一個變數,讀寫這個變數時,表示讀寫記憶體地址 0x601038 處存放的資料值。
  2. 在C語言中,要想取得 phone_num的記憶體地址,則需要使用表示式&phone_num
  3. 與組合語言相比,顯然 C 語言提高了抽象層次,也造成了同一個符號在不同語言中代表不同的含義。使用時務必小心,以防混淆。

【完】


參考資料
https://blog.csdn.net/smstong/article/details/54405649

相關文章