日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ARM 汇编基础教程番外篇 ——配置实验环境

發(fā)布時間:2024/7/23 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ARM 汇编基础教程番外篇 ——配置实验环境 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

From:https://zhuanlan.zhihu.com/p/29145513

?

win10 arm 匯編環(huán)境

Windows 平臺下搭建 ARM 匯編集成環(huán)境:https://jingyan.baidu.com/article/4b52d70288bfcdfc5c774ba5.html

?

要調(diào)試 ARM 程序,我們需要:

  • 能運行 ARM 程序的運行環(huán)境。
  • 支持 ARM 架構(gòu)的調(diào)試器。

本篇教程將基于 x86 平臺的 Ubuntu 20,介紹如何搭建 ARM 的交叉編譯、運行和調(diào)試環(huán)境。

?

?

?

交叉編譯環(huán)境

?

Ubuntu 20 的源中提供了多個 arm-gcc 的軟件包,以 gcc 5 為例可以通過 "apt search"?命令找到 "gcc-5-arm-linux-gnueabi"?和 "gcc-5-arm-linux-gnueabihf"?兩個軟件包。這兩個軟件包安裝的編譯工具是一樣的,只是與浮點數(shù)相關(guān)的默認編譯選項不同。由于我們虛擬的環(huán)境沒有 FPU,只需要安裝 "gcc-5-arm-linux-gnueabi"?就可以了。

安裝完成后可以在 "/usr/bin/arm-linux-gnueabi-*" 找到相關(guān)的編譯工具鏈,包含常用的 gcc、as 和 ld 等。

只要使用如下兩條命令,就可以實現(xiàn)對 ARM 匯編的編譯:

$ arm-linux-gnueabi-as [source file] –o [object file] $ arm-linux-gnueabi-ld [object file] –o [executable file]

可以使用如下命令編譯經(jīng)典的 "hello world"?程序,用于后續(xù)章節(jié)的實驗:

$ arm-linux-gnueabi-gcc-5 hello.c –g –o hello -static

示例截圖:

?

?

arm-linux-gcc 安裝方法

?

From:Ubuntu 18.04安裝arm-linux-gcc交叉編譯器 :https://www.cnblogs.com/tansuoxinweilai/p/11602830.html

方法 一:

我們都知道 Ubuntu 有一個專門用來安裝軟件的工具 apt,我們可以用它來全自動安裝 arm-linux-gcc。

首先 Ctrl+Alt+T 彈出終端,使用如下命令進行 arm-linux-gcc 的安裝:

sudo apt-get install gcc-arm-linux-gnueabihf

使用如下命令進行 arm-linux-g++ 的安裝:

sudo apt-get install g++-arm-linux-gnueabihf

如果要卸載時使用如下命令進行移除,arm-linux-gcc 的卸載:

sudo apt-get remove gcc-arm-linux-gnueabihf

arm-linux-g++ 的卸載:

sudo apt-get remove g++-arm-linux-gnueabihf

?

方法 二:

64 位的 Ubuntu 系統(tǒng),那就安裝64位的arm-linux-gcc交叉編譯器,直接安裝就能成功:
例如:arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2??
下載地址:https://pan.baidu.com/s/1xuh8M8bQHfZt_w6h4vRKeg??提取碼:uk85?

1. 先把下載好的安裝包移動到根目錄下的tmp目錄中( /tmp )
2. 使用 tar 命令解壓安裝包,即在Terminal中輸入以下命令:( 前面的 sudo 表示使用 root 權(quán)限執(zhí)行該命令 )

sudo tar -xjvf /tmp/arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2 -C /

注意是大寫的字母 C,此命令會把安裝包解壓到根目錄下的 opt 的 TuxamitoSoftToolchains里面(/opt/TuxamitoSoftToolchains)

如圖逐層查看找到 gcc-4.6.4 所在的位置:/opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi

3. 解壓完成后,再在(/usr/local)中創(chuàng)建一個新目錄 arm,即在 Terminal 中輸入以下命令:

sudo mkdir /usr/local/arm

創(chuàng)建 arm 目錄成功后,還需要給它解放全部權(quán)限,即在 Terminal 中輸入以下命令:

sudo chmod 777 /usr/local/arm

4. 在解壓出來的目錄中找到并把整個 gcc-4.6.4目錄復(fù)制到剛剛建好的arm目錄中,命令如下:

先 cd 切換到 gcc-4.6.4 所在目錄(切換后先ls看一下有沒有 gcc-4.6.4 目錄):

cd /opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/

再執(zhí)行 cp 復(fù)制命令,-r 表示整個目錄以及里面的任何東西

sudo cp -r gcc-4.6.4 /usr/local/arm

5.打開(/etc/profile)配置環(huán)境變量和庫變量,目的是以后可以在任何位置使用該交叉編譯器,命令如下:

sudo vi /etc/profile

用 vi 或者 vim 打開后,在文件最后添加兩行,并輸入以下代碼:第一行是添加執(zhí)行程序的環(huán)境變量,第二行是庫文件的路徑

export PATH=$PATH:/usr/local/arm/gcc-4.6.4/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/gcc-4.6.4/lib

然后保存退出即可。

6. 使用 source 命令重新加載生效該配置文件

source /etc/profile

7.檢驗是否安裝成功,在 Terminal 輸入以下命令輸出版本信息:

arm-linux-gcc -v

結(jié)果如圖所示:得到剛剛安裝的4.6.4版

再隨便寫一個 1.c 文件,能編譯成功說明已經(jīng)完美安裝。例如:

arm-linux-gcc 1.c -o pp

再 file 命令查看編譯后的是不是 arm 的可執(zhí)行文件:

file pp

可以看到編譯后的可執(zhí)行文件是在 32-bit 的 ARM 架構(gòu)上運行的。

?

注意:有些做完上述步驟還是不能用arm-linux-gcc的話,出現(xiàn)如下圖所示錯誤:

這和時候需要在 “/home/用戶名” 目錄下的 ".bashrc" 隱藏文件下加上和 “/etc/profile” 一樣的兩句

export PATH=$PATH:/usr/local/arm/gcc-4.6.4/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/gcc-4.6.4/lib

這個 ".bashrc" 是一個隱藏文件,需要? ls -a 命令才能看見!用戶名就是你自己的linux登錄賬號。

同樣用 vi或者vim打開它,在最后添加兩行:

?

?

?

運行環(huán)境

?

QEMU 來創(chuàng)建一個,[教程在這]:https://blog.csdn.net/zerokkqq/article/details/79621769

?

1. qemu-user-static

最簡單的運行環(huán)境是使用 qemu-user-static 模擬運行靜態(tài)編譯的可執(zhí)行程序。

我們可以使用如下命令模擬運行上一節(jié)創(chuàng)建的 hello 程序:

# 首先安裝 qemu-user-static,若已安裝可以忽略這一步 $ sudo apt install qemu-user-static # 直接執(zhí)行 hello 程序 $ qemu-arm-static hello # 啟動 gdbserver 等待 gdb 連接 $ qemu-arm-static –g [gdbserver port] hello

上述命令運行后會啟動一個 qemu 自帶的 gdbserver,監(jiān)聽你通過 "-g"?選項指定的端口。可以在另一個窗口中啟動 gdb 進行遠程調(diào)試(遠程調(diào)試的細節(jié),將在第三章介紹)。

?

Linux 下 ARM 程序的編譯運行及調(diào)試:https://www.jianshu.com/p/dc8e263d6466

  • 安裝 qemu

    sudo apt-get install qemu qemu-arm-static qemu-kvm-extras

  • arm 程序的編譯運行

  • 編譯:arm-linux-gcc -o hello-arm hello.c
  • 運行:qemu-arm hello-arm
  • 安裝 gdb-multiarch

    sudo apt-get install gdb-multiarch

  • arm 程序的調(diào)試

  • 利用 gdb 對 qemu-arm 運行的程序進行遠程 gdb 調(diào)試,首先是在終端中輸入如下指令等待調(diào)試:qemu-arm -g 1234 hello-arm
  • 再打開另外一個終端,并在其中利用 arm-linux-gdb 進入調(diào)試器,并通過端口 1234 連接到 qemu-arm 等待調(diào)試的程序:gdb-multiarch hello-arm


?

?

2. 虛擬 Raspberry

ARM匯編學(xué)習(xí)(一)搭建ARM匯編模擬環(huán)境(?圖文教程?):https://www.veryarm.com/65170.html

qemu-user-static 的方式比較簡單,但功能也很局限,Azeria-labs 的教程中介紹了另一種方法,使用 qemu 創(chuàng)建一臺虛擬樹莓派。首先你需要安裝 qemu-system :

$ sudo apt install qemu-system

為了虛擬一臺樹莓派,你還需要下載專為樹莓派定制的debian鏡像(raspbian)和支持樹莓派的內(nèi)核文件。

raspbian鏡像下載地址:https://www.raspberrypi.org/downloads/raspbian/

樹莓派內(nèi)核下載地址:https://github.com/dhruvvyas90/qemu-rpi-kernel

?

Raspbian 的鏡像有兩個版本,一個帶圖形界面的完整版和一個沒有圖形界面的 lite 版本,對于我們的實驗而言 lite 版本就足夠了。內(nèi)核文件有多個,選擇內(nèi)核版本最新的那個就可以了。下載完上述文件后,創(chuàng)建一個“arm_vm”目錄,將上述文件一起放置在該目錄下。然后執(zhí)行如下命令:

$ unzip <image-file>.zip $ fdisk –l <image-file>

你應(yīng)該可以看到,類似如下內(nèi)容:

Disk 2017-08-16-raspbian-stretch-lite.img: 1.7 GiB, 1854418944 bytes, 3621912 sectorsUnits: sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisklabel type: dosDisk identifier: 0xee397c53Device Boot Start End Sectors Size Id Type2017-08-16-raspbian-stretch-lite.img1 8192 93813 85622 41.8M c W95 FAT32 (LBA)2017-08-16-raspbian-stretch-lite.img2 94208 3621911 3527704 1.7G 83 Linux

注意標紅的部分,可以看到文件系統(tǒng)從94208扇區(qū)開始。我們將這個值乘以512,本例中為“94208 * 512=48234496”,這就是文件系統(tǒng)其實位置的偏移字節(jié)數(shù),在下面的命令中我們會用到:

$ sudo mkdir /mnt/raspbian $ sudo mount -v -o offset=48234496 -t ext4 [path-of-your-img-file.img] /mnt/raspbian $ sudo vi /mnt/raspbian/etc/ld.so.preload 將上述文件中的所有內(nèi)容用“#”注釋掉,保存修改并退出。 $ sudo vi /mnt/raspbian/etc/fstab

如果fstab文件中有出現(xiàn)mmcblk0字符串,那么將“/dev/mmcblk0p1”替換為“/dev/sda1”,將“/dev/mmcblk0p2”替換為“/dev/sda2”,保存后退出。至此,系統(tǒng)配置的修改完成,可以將“/mnt/raspbian”卸載掉。

$ sudo umount /mnt/raspbian

你可以進入“arm_vm”目錄,使用如下腳本啟動虛擬機:

#!/usr/bin/env bashqemu-system-arm -kernel kernel-qemu-4.4.34-jessie \ -cpu arm1176 \ -m 256 \ -M versatilepb \ -serial stdio \ -append "root=/dev/sda2 rootfstype=ext4 rw" \ -drive format=raw,file=2017-08-16-raspbian-stretch-lite.img \ -redir tcp:5022::22 \# 為ssh預(yù)留 -redir tcp:3011::3011 \# 為gdbserver預(yù)留,用于遠程調(diào)試 -no-reboot 1> /dev/null 2>&1 &

虛擬機啟動后默認的登錄密碼是“raspberry”。為了更方便的使用虛擬機,我們需要開啟ssh服務(wù),并設(shè)置開機啟動。

$ sudo service ssh start $ sudo update-rc.d ssh enable

此時,你應(yīng)該已經(jīng)可以使用如下命令,通過ssh訪問虛擬機了:

$ ssh pi@127.0.0.1 -p 5022

我們可以使用scp命令通過ssh,將上一節(jié)編譯的hello程序上傳到虛擬機中執(zhí)行:

scp -P 5022 hello pi@127.0.0.1:/tmp

進入虛擬機的tmp目錄,可以看到我們上傳的hello程序嘗試執(zhí)行,應(yīng)該會輸出久違的“hello world!”,說明我們的交叉編譯環(huán)境搭建是正確的。至此我們的虛擬樹莓派環(huán)境搭建完畢。

?

?

調(diào)試環(huán)境

調(diào)試環(huán)境的搭建是最重要的也是坑最多的。為了模擬真實IoT安全實戰(zhàn)中遠程調(diào)試的場景,我們將介紹如何交叉編譯gdbserver并上傳至虛擬機進行遠程調(diào)試。為了獲得類似pwndbg那樣強大的調(diào)試效果,我們將介紹如何安裝使用專為IoT安全設(shè)計的gef增強腳本。

?

1. gdb-multiarch

在使用gdb進行調(diào)試之前,我們需要先安裝gdb-multiarch。顧名思義,它是gdb支持多中硬件體系架構(gòu)的版本。之所以要安裝gdb-multiarch,是因為Ubuntu默認安裝的gdb只支持x86/x64架構(gòu),你可以啟動gdb然后輸入命令“set
architecture arm”查看,gdb會提示錯誤。

# 安裝gdb-multiarch $ sudo apt install gdb-multiarch # 啟動gdb-multiarch $ gdb-multiarch

?

2. 編譯 gdbserver

在分析IoT設(shè)備的安全性時,我們往往需要上傳gdbserver進行遠程調(diào)試。在我們的實驗環(huán)境中(事實上我們的Raspbian系統(tǒng)自帶gdb),我們也可以模擬搭建一個遠程調(diào)試環(huán)境。首先,我們需要獲取gdb的源碼(包含了gdb源碼和gdbserver源碼),版本需要與我們本地的gdb版本一致,因為gdbserver需要與gdb版本保持一致,否則容易出現(xiàn)非預(yù)期的問題。你可以在這個地址,找到gdb各版本的源碼:http://ftp.gnu.org/gnu/gdb/。

?

下載解壓后進入“gdb-<version>/gdb/gdbserver”目錄,使用如下命令編譯安裝:

$CC="arm-linux-gnueabi-gcc-5" CXX="arm-linux-gnueabi-g++-5" ./configure --target=arm-linux-gnueabi --host="arm-linux-gnueabi" --prefix="setup-directory" $ make install

然后,在你通過“--prefix”選項指定的路徑下,就可以找到編譯完成的gdbserver了。使用file命令查看,應(yīng)該可以看到類似如下輸出:

$ file arm-linux-gnueabi-gdbserver arm-linux-gnueabi-gdbserver:ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=32ad2025951ee428276ac2fbadb199bfd39e2278, not stripped

使用scp將gdbserver上傳到我們的虛擬樹莓派中并啟動:

$ ln -s arm-linux-gnueabi-gdbserver gdbserver $ gdbserver 0.0.0.0:2333 hello Process hello created; pid = 702 Listening on port 2333

至此,我們的遠程調(diào)試環(huán)境搭建完畢,下一節(jié),我們將引入gef增強腳本。

?

3. gef 增強腳本

gef是一個支持多種硬件體系結(jié)構(gòu)的gdb增強腳本,非常適合IoT安全領(lǐng)域應(yīng)對多變的硬件平臺。你可以參考github主頁(https://github.com/hugsy/gef)的README,進行安裝配置。不過需要注意的是,gef依賴的第三方模塊keystone-engine需要手動安裝,因為pip源提供的安裝是無效的。建議先通過pip安裝,如果安裝后gef的部分功能仍無法使用,可以卸載通過pip安裝的第三方模塊,在github上(https://github.com/keystone-engine/keystone)下載最新源碼,手動編譯安裝(參見:http://www.keystone-engine.org/docs/)。

安裝完成后開啟gdb調(diào)試,你將看到類似如下的界面:

首先設(shè)置目標硬件體系架構(gòu)為arm:

gef> set architecture arm

我們使用gef-remote命令連接gdbserver,如果使用gdb自帶的“target remote”命令會出現(xiàn)一些非預(yù)期的問題(參見:https://github.com/hugsy/gef/issues/7)。

gef> gef-remote –q 127.0.0.1:2333

你應(yīng)該能看到類似如下的輸出:

至此,我們的調(diào)試環(huán)境配置完畢了。

?

?

擴展閱讀

?

[1] gef官方文檔,http://gef.readthedocs.io/en/master/

[2] gdb調(diào)試利器,http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/gdb.html

[3] gdb中應(yīng)該知道的幾個調(diào)試方法,https://coolshell.cn/articles/3643.html

本文由看雪翻譯小組 ljcnaix 原創(chuàng) 轉(zhuǎn)載請注明來自看雪社區(qū)

?

?

?

ARM匯編ARM GNU匯編 區(qū)別

?

ARM 匯編 與 ARM GNU匯編 區(qū)別:https://blog.csdn.net/tabactivity/article/details/90054443

?

一、ARM匯編開發(fā)的兩種的方式

ARM 匯編開發(fā),有兩種開發(fā)方式,一種是使用 ARM 匯編,一種是使用 ARM GNU 匯編。兩種匯編開發(fā),使用的匯編指令是完全一樣的,區(qū)別是宏指令,偽指令,偽操作不一樣。其實兩種開發(fā)方式的區(qū)別在于所使用的編譯工具不一樣。

對于 ARM 匯編,使用的是 ARM 公司開發(fā)的編譯器,而 ARM GNU 匯編,是使用 GNU 為 ARM 指令集開發(fā)的編譯器,也就是arm-gcc。

?

二、ARM的編譯開發(fā)環(huán)境

兩種常用的 ARM 的編譯開發(fā)環(huán)境

  • DS5:ARM 提供的集成開發(fā)軟件。使用的是 ARM 提供的工具鏈進行程序編譯

  • GNU 開發(fā)環(huán)境: 由 GNU 的匯編器 as,交叉編譯器 gcc,和 鏈接器ld 等組成

?

三、偽操作,宏指令,偽指令

  • 偽操作:ARM 匯編語言程序里的一些特殊指令助記符,其作用主要是完成匯編程序做各種準備工作,在源程序進行匯編時由匯編程序處理,而不是在計算機運行期間由機器執(zhí)行。如程序段的定義,就屬于偽操作。
  • 宏指令:一段獨立的程序代碼,可插在源程序中,通過偽操作來定義。
  • 偽指令:ARM 匯編語言程序里的一些特殊指令助記符,不在處理器運行期間執(zhí)行,在匯編時,被合適的ARM的機器指令代替,從而實現(xiàn)真正的指令操作。

?

四、ARM 匯編偽操作

偽操作

語法格式

作用

GBLA

GBLA ?Varible

聲明一個全局的算術(shù)變量,并將其初始化為0

GBLL

GBLL ?Varible

聲明一個全局的邏輯變量,并將其初始化成{FALSE}

GBLS

GBLS ?Varible

聲明一個全局的字符串變量,并將其初始化成空串

LCLA

LCLA ?Varible

聲明一個局部的算術(shù)變量,并將其初始化為0

LCLL

LCLL ?Varible

聲明一個局部的邏輯變量,并將其初始化成{FALSE}

LCLS

LCLS ?Varible

聲明一個局部的字符串變量,并將其初始化成空串

SETA

SETA ?Varible ?expr

給一個全局或局部算術(shù)變量賦值

SETL

SETL ?Varible ?expr

給一個全局或局部邏輯變量賦值

SETS

SETS ?Varible ?expr

給一個全局或局部字符串變量賦值

RLIST

name LIST {list of registers}

為一個通用寄存器列表定義名稱

CN

name CN expr

為一個協(xié)處理器的寄存器定義名稱

CP

name CP expr

為一個協(xié)處理器定義名稱

DN/SN

name DN/SN expr

DN/SN為一個雙精度/單精度的VFP寄存器定義名稱

FN

name FN ?expr

為一個FPA浮點寄存器定義名稱

LTORG

LTONG

聲明一個數(shù)據(jù)緩沖池(文字池)的開始

MAP

MAP expr {, base-register}

定義一個結(jié)構(gòu)化的內(nèi)存表(storage map)的首地址

FIELD

{label} ?FIELF ?expr

定義一個結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域

SPACE

{label} ?SPACE ?expr

分配一塊連續(xù)內(nèi)存單元,并用0初始化

DCB

{label} ?DCB ?expr {,expr}..

分配一塊字節(jié)內(nèi)存單元,并用expr初始化

DCD/ DCDU

{label} DCD/DCDU expr {,expr}…

分配一塊字內(nèi)存單元, 并用expr初始化

DCDO

{label} ?DCDO ?expr {,expr}…

分配一塊字對齊的字內(nèi)存單元, 并用expr初始化

DCFD/DCFDU

{label} ? DCFD{U} ? fpliteral

,{,fpliteral}…

為雙精度的浮點數(shù)分配字對齊的內(nèi)存單元

DCFS/DCFSU

{label} ? ?DCFS{U} ?fpliteral

,{,fpliteral}…

為單精度的浮點數(shù)分配字對齊的內(nèi)存單元

DCI

{label} DCI expr, {expr}…

ARM代碼分配一段字對齊的內(nèi)存單元,填充expr(二進制指令碼),THUMB代碼中,分配一段半字對齊的半字內(nèi)存單元。

DCQ/ DCQU

{label} DCQ{U} ?{-} literal,

{, {-} literal}…

分配一段以雙字(8個字節(jié))為單位的內(nèi)存

DCW/DCWU

{label} DCW{U} ?{-} literal,

{, {-} literal}…

DCW用于分配一段半字對齊的半字內(nèi)存單元

?

  • 1、AREA:創(chuàng)建一段新的程序代碼或數(shù)據(jù)區(qū)。? ? ? ??
    ?? ??? ?格式 : ??AREA ?name, {,attr,} …
    ? ? ? ? 其中,name是程序段名, atrr是段名屬性
    ? ? ? ? 對于屬性,有以下一些:
    ? ? ? ? ? ? ? ? CODE: 用于定義代碼段,默認為是READONLY
    ? ? ? ? ? ? ? ? DATA: 用于定于數(shù)據(jù)段,默認為READWRITE
    ? ? ? ? ? ? ? ? READONLY: 指定本段的內(nèi)容只讀
    ? ? ? ? ? ? ? ? READWRITE: ?指定本段的內(nèi)容可讀可寫
    ? ? ? ? ? ? ? ? ALIGN: ?指定對齊為2次冪
    ? ? ? ? ? ?COMMON: 定義通用的段。不包含任何用戶的代碼和數(shù)據(jù)。各源文件中同名的COMMON屬性段共享同一段存儲單元

  • 2、ALIGN:指定對齊
    ? ? ? ? ? ? ALIGN ?4 ?表示4字節(jié)地址對齊
    ? ? ? ? ? ? ALIGN ?8 ?表示8字節(jié)地址對齊
    ? ? ? ? ? ? 注意:在AREA中使用和單獨使用ALIGN的區(qū)別,在于格式和對齊的計算不一樣。
  • 3、ENTRY:指定匯編程序的入口。
    ? ? ? ? 一個程序至少有一個入口點,也可以有多個入口點,但是在一個源文件中,最多只能有一個ENTRY。
    ? ? ? ? 當(dāng)多個源文件均有ENTRY時,由鏈接器指定程序真正的入口。
  • 4、END:表示源程序的結(jié)束。所以匯編語言源文件必須以END結(jié)束,匯編器遇到END, 將結(jié)束編譯。
  • 5、EXPORT
    ? ? ? ? 格式: EXPORT ?標號 ?[,WEAK]
    ? ? ? ? 聲明一個全局標號,其他源文件可以使用這個標號。WEAK表示碰上其他同名標號時,其他標號優(yōu)先。
  • 6、IMPORT
    ? ? ? ? 格式: ??IMPORT 標號,[,WEAK]
    ? ? ? ? 表示該引用的標號在其他源文件中,單要在當(dāng)前文件中引用。
    ? ? ? ? WEAK表示找不到該標號時,也不報錯,一般該標號置為0,如果是B 或BL指令用到該標號,該指令置為nop。
    ? ? ? ? 該標號會加入到當(dāng)前源文件的符號表中。

  • 7、EXTERN:和 IMPORT 一樣,不同在于,如果當(dāng)前文件沒有引用該標號,該標號不會加入到當(dāng)前源文件的符號表中。
  • 8、GET ( 或 INCLUDE ):將一個源文件包含到當(dāng)前的源文件中
  • 9、EQU:對一個常量標號賦值
    ? ? ? ? 格式: ?name ??EQU ??expression
    ? ? ? ? 其中: name符號名, expression寄存器相關(guān)或者程序相關(guān)的固定值
    ? ? ? ? 如:num ??EQU ??2 ?; ?為符號賦予數(shù)字2
    ? ? ? ? EQU,等同于C語言中用#define定義一個常量
  • 10、SPCAE:用于分配一片連續(xù)內(nèi)存單元,并用0初始化。SPACE 可用 % 代替。
    ? ? ? ? 格式: {label} SPACE expr
    ? ? ? ? label : 是一個標號, 可選
    ? ? ? ? expr: ??分配的內(nèi)存字節(jié)數(shù)
    ? ? ? ? 如:stack SPACE 100 ; 分配100個字節(jié)內(nèi)存單元,并用0初始化。標號stack是這片空間的起始地址
  • 11、DCB:用于分配段字節(jié)內(nèi)存單元,并用偽操作中的expr初始化。
    ? ? ? ? 格式: {label} DCB expr {,expr}
    ? ? ? ? label: 是一個標號,可選
    ? ? ? ? expr: 可以是-128~255的數(shù)值或者字符串
    ? ? ? ? 如:string ?DCB ?"HELLO" ??;為HELLO字符串分配空間, string是這塊空間的起始地址
  • 12、DCD 及 DCDU:用于分配段字內(nèi)存單元(分配的內(nèi)存都是字對齊,DCDU并不嚴格字對齊),并用偽操作中的expr初始化。 DCD 可用 & 代替。
    ? ? ? ? 格式: {label} DCD expr, {,expr}
    ? ? ? ? label: 是一個標號,可選,表示這塊內(nèi)存單元的首地址
    ? ? ? ? expr: 數(shù)字表達式或程序中的標號
    ? ? ? ? 如:data DCD ?1,2,3,4 ????;分配字對齊的字單元空間,初始化為1,2,3,4

?

?

五、ARM匯編偽指令

?

ARM偽指令包括: ADR, ADRL,LDR ,NOP

THUMB偽指令包括:ADR, LDR, NOP

偽指令

語法格式

作用

ADR

ADR{cond} register, expr

將基于PC或基于寄存器的地址值讀取到寄存器中。小范圍的地址讀取

ADRL

ADRL{cond} register, expr

將給予PC或基于寄存器的地址值讀取到寄存器中。中等范圍的地址讀取

LDR

LDR {cond} register,

=[expr|label]

將一個32位的立即數(shù)或者一個地址值讀取到寄存器中。大范圍的地址讀取

NON

NOP

在匯編時,被替換成空操作

?

六、ARM GNU 編譯環(huán)境

?

偽操作

語法格式

作用

.byte

.byte expr {,expr}…

分配一段字節(jié)內(nèi)存單元,并用expr初始化

.hword/.short

.hword expr {,expr}…

分配一段半字內(nèi)存單元,并用expr初始化

.ascii

.ascii expr {,expr}…

定義字符串expr

.asciz/.string

.asciz expr {,expr}…

定義字符串expr(會增加/0為結(jié)束符)

.floar/.single

.float expr {,expr}…

定義32bit IEEE浮點數(shù)expr

.double

.doubel expr {,expr}…

定義64bit IEEE浮點數(shù)expr

.word/.long/.int

.word expr {,expr}…

分配一段字內(nèi)存單元,并用expr初始化

.fill

.fill ?repeat {,size} {,value}

分配一段字節(jié)內(nèi)存單元,用sieze長度value填充repeat次

.zero

.zero size

分配一段字節(jié)內(nèi)存單元,并用0填充內(nèi)存

.space/.skip

.space size, {,value}

分配一段內(nèi)存單元,用value將內(nèi)存初始化

.section

.section expr

定義一個段

.text

.text {subsection}

代碼段,

.data

.data{subsection}

數(shù)據(jù)段

.bss

.bss{subsection}

bss段

.cond 16/.thumb

.code 16/.thumb

表示之后的匯編指令使用THUMB指令集

.code 32/.arm

.code 32/.arm

表示之后的匯編指令使用ARM指令集

.end

.end

標記匯編文件的結(jié)束

.include

.include "filename"

將一個源文件包含到當(dāng)前源文件中

.align/.balign

.align {alignment} {,fill},{max}

通過填充字節(jié)使當(dāng)前位置滿足一定的對齊格式

?

七、兩種開發(fā)環(huán)境的區(qū)別

?

兩種開發(fā)環(huán)境下的匯編代碼,有較多不同的點,主要是符號及偽操作的不同。

ARM匯編的偽操作符

GNU匯編的偽操作符

INLCUDE

.include

NUM ? ?EQU ? 25

.equ ?NUM, ?25

EXPORT

.global

IMPORT

.extern

DCD

.long

IF: ?DEF:

.ifdef

ELSE

.else

ENDIF

.endif

OR

|

SHL

<<

RN

.req

GBLA

.global

NUM ?SETA 16

.equ ? NUM , 16

MACRO

.macro

MEND

.endm

END

.end

AREA WORD, CODE, READONLY

.text

AREA BLOCK, DATE, READWRITE

.data

CODE32

.arm

CODE16

.thumb

LTORG

.ltorg

%

.fill

ENTRY

ENTRY:

ldr x0,=0xff

ldr x0,=0xff

原文鏈接:http://www.lujun.org.cn/?p=3943

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的ARM 汇编基础教程番外篇 ——配置实验环境的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。