From:https://zhuanlan.zhihu.com/p/29145513
win10 arm 彙編環境
Windows 平臺下搭建 ARM 彙編集成環境:https://jingyan.baidu.com/article/4b52d70288bfcdfc5c774ba5.html
要調試 ARM 程序,我們需要:
- 能運行 ARM 程序的運行環境。
- 支持 ARM 架構的調試器。
本篇教程將基於 x86 平臺的 Ubuntu 20,介紹如何搭建 ARM 的交叉編譯、運行和調試環境。
交叉編譯環境
Ubuntu 20 的源中提供了多個 arm-gcc 的軟件包,以 gcc 5 爲例可以通過 "apt search" 命令找到 "gcc-5-arm-linux-gnueabi" 和 "gcc-5-arm-linux-gnueabihf" 兩個軟件包。這兩個軟件包安裝的編譯工具是一樣的,只是與浮點數相關的默認編譯選項不同。由於我們虛擬的環境沒有 FPU,只需要安裝 "gcc-5-arm-linux-gnueabi" 就可以了。
安裝完成後可以在 "/usr/bin/arm-linux-gnueabi-*" 找到相關的編譯工具鏈,包含常用的 gcc、as 和 ld 等。
只要使用如下兩條命令,就可以實現對 ARM 彙編的編譯:
$ arm-linux-gnueabi-as [source file] –o [object file]
$ arm-linux-gnueabi-ld [object file] –o [executable file]
可以使用如下命令編譯經典的 "hello world" 程序,用於後續章節的實驗:
$ 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 系統,那就安裝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 權限執行該命令 )
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)中創建一個新目錄 arm,即在 Terminal 中輸入以下命令:
sudo mkdir /usr/local/arm
創建 arm 目錄成功後,還需要給它解放全部權限,即在 Terminal 中輸入以下命令:
sudo chmod 777 /usr/local/arm
4. 在解壓出來的目錄中找到並把整個 gcc-4.6.4目錄複製到剛剛建好的arm目錄中,命令如下:
先 cd 切換到 gcc-4.6.4 所在目錄(切換後先ls看一下有沒有 gcc-4.6.4 目錄):
cd /opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/
再執行 cp 複製命令,-r 表示整個目錄以及裏面的任何東西
sudo cp -r gcc-4.6.4 /usr/local/arm
5.打開(/etc/profile)配置環境變量和庫變量,目的是以後可以在任何位置使用該交叉編譯器,命令如下:
sudo vi /etc/profile
用 vi 或者 vim 打開後,在文件最後添加兩行,並輸入以下代碼:第一行是添加執行程序的環境變量,第二行是庫文件的路徑
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
結果如圖所示:得到剛剛安裝的4.6.4版
再隨便寫一個 1.c 文件,能編譯成功說明已經完美安裝。例如:
arm-linux-gcc 1.c -o pp
再 file 命令查看編譯後的是不是 arm 的可執行文件:
file pp
可以看到編譯後的可執行文件是在 32-bit 的 ARM 架構上運行的。
注意:有些做完上述步驟還是不能用arm-linux-gcc的話,出現如下圖所示錯誤:
這和時候需要在 “/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打開它,在最後添加兩行:
運行環境
QEMU 來創建一個,[教程在這]:https://blog.csdn.net/zerokkqq/article/details/79621769
1. qemu-user-static
最簡單的運行環境是使用 qemu-user-static 模擬運行靜態編譯的可執行程序。
我們可以使用如下命令模擬運行上一節創建的 hello 程序:
# 首先安裝 qemu-user-static,若已安裝可以忽略這一步
$ sudo apt install qemu-user-static
# 直接執行 hello 程序
$ qemu-arm-static hello
# 啓動 gdbserver 等待 gdb 連接
$ qemu-arm-static –g [gdbserver port] hello
上述命令運行後會啓動一個 qemu 自帶的 gdbserver,監聽你通過 "-g" 選項指定的端口。可以在另一個窗口中啓動 gdb 進行遠程調試(遠程調試的細節,將在第三章介紹)。
Linux 下 ARM 程序的編譯運行及調試: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 程序的調試
- 利用 gdb 對 qemu-arm 運行的程序進行遠程 gdb 調試,首先是在終端中輸入如下指令等待調試:
qemu-arm -g 1234 hello-arm
- 再打開另外一個終端,並在其中利用 arm-linux-gdb 進入調試器,並通過端口 1234 連接到 qemu-arm 等待調試的程序:
gdb-multiarch hello-arm
- 利用 gdb 對 qemu-arm 運行的程序進行遠程 gdb 調試,首先是在終端中輸入如下指令等待調試:
2. 虛擬 Raspberry
ARM彙編學習(一)搭建ARM彙編模擬環境( 圖文教程 ):https://www.veryarm.com/65170.html
qemu-user-static 的方式比較簡單,但功能也很侷限,Azeria-labs 的教程中介紹了另一種方法,使用 qemu 創建一臺虛擬樹莓派。首先你需要安裝 qemu-system :
$ sudo apt install qemu-system
爲了虛擬一臺樹莓派,你還需要下載專爲樹莓派定製的debian鏡像(raspbian)和支持樹莓派的內核文件。
raspbian鏡像下載地址:https://www.raspberrypi.org/downloads/raspbian/
樹莓派內核下載地址:https://github.com/dhruvvyas90/qemu-rpi-kernel
Raspbian 的鏡像有兩個版本,一個帶圖形界面的完整版和一個沒有圖形界面的 lite 版本,對於我們的實驗而言 lite 版本就足夠了。內核文件有多個,選擇內核版本最新的那個就可以了。下載完上述文件後,創建一個“arm_vm”目錄,將上述文件一起放置在該目錄下。然後執行如下命令:
$ unzip <image-file>.zip
$ fdisk –l <image-file>
你應該可以看到,類似如下內容:
Disk 2017-08-16-raspbian-stretch-lite.img: 1.7 GiB, 1854418944 bytes, 3621912 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xee397c53
Device Boot Start End Sectors Size Id Type
2017-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
注意標紅的部分,可以看到文件系統從94208扇區開始。我們將這個值乘以512,本例中爲“94208 * 512=48234496”,這就是文件系統其實位置的偏移字節數,在下面的命令中我們會用到:
$ 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
將上述文件中的所有內容用“#”註釋掉,保存修改並退出。
$ sudo vi /mnt/raspbian/etc/fstab
如果fstab文件中有出現mmcblk0字符串,那麼將“/dev/mmcblk0p1”替換爲“/dev/sda1”,將“/dev/mmcblk0p2”替換爲“/dev/sda2”,保存後退出。至此,系統配置的修改完成,可以將“/mnt/raspbian”卸載掉。
$ sudo umount /mnt/raspbian
你可以進入“arm_vm”目錄,使用如下腳本啓動虛擬機:
#!/usr/bin/env bash
qemu-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預留
-redir tcp:3011::3011 \# 爲gdbserver預留,用於遠程調試
-no-reboot 1> /dev/null 2>&1 &
虛擬機啓動後默認的登錄密碼是“raspberry”。爲了更方便的使用虛擬機,我們需要開啓ssh服務,並設置開機啓動。
$ sudo service ssh start
$ sudo update-rc.d ssh enable
此時,你應該已經可以使用如下命令,通過ssh訪問虛擬機了:
$ ssh [email protected] -p 5022
我們可以使用scp命令通過ssh,將上一節編譯的hello程序上傳到虛擬機中執行:
scp -P 5022 hello [email protected]:/tmp
進入虛擬機的tmp目錄,可以看到我們上傳的hello程序嘗試執行,應該會輸出久違的“hello world!”,說明我們的交叉編譯環境搭建是正確的。至此我們的虛擬樹莓派環境搭建完畢。
調試環境
調試環境的搭建是最重要的也是坑最多的。爲了模擬真實IoT安全實戰中遠程調試的場景,我們將介紹如何交叉編譯gdbserver並上傳至虛擬機進行遠程調試。爲了獲得類似pwndbg那樣強大的調試效果,我們將介紹如何安裝使用專爲IoT安全設計的gef增強腳本。
1. gdb-multiarch
在使用gdb進行調試之前,我們需要先安裝gdb-multiarch。顧名思義,它是gdb支持多中硬件體系架構的版本。之所以要安裝gdb-multiarch,是因爲Ubuntu默認安裝的gdb只支持x86/x64架構,你可以啓動gdb然後輸入命令“set
architecture arm”查看,gdb會提示錯誤。
# 安裝gdb-multiarch
$ sudo apt install gdb-multiarch
# 啓動gdb-multiarch
$ gdb-multiarch
2. 編譯 gdbserver
在分析IoT設備的安全性時,我們往往需要上傳gdbserver進行遠程調試。在我們的實驗環境中(事實上我們的Raspbian系統自帶gdb),我們也可以模擬搭建一個遠程調試環境。首先,我們需要獲取gdb的源碼(包含了gdb源碼和gdbserver源碼),版本需要與我們本地的gdb版本一致,因爲gdbserver需要與gdb版本保持一致,否則容易出現非預期的問題。你可以在這個地址,找到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命令查看,應該可以看到類似如下輸出:
$ 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
至此,我們的遠程調試環境搭建完畢,下一節,我們將引入gef增強腳本。
3. gef 增強腳本
gef是一個支持多種硬件體系結構的gdb增強腳本,非常適合IoT安全領域應對多變的硬件平臺。你可以參考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調試,你將看到類似如下的界面:
首先設置目標硬件體系架構爲arm:
gef> set architecture arm
我們使用gef-remote命令連接gdbserver,如果使用gdb自帶的“target remote”命令會出現一些非預期的問題(參見:https://github.com/hugsy/gef/issues/7)。
gef> gef-remote –q 127.0.0.1:2333
你應該能看到類似如下的輸出:
至此,我們的調試環境配置完畢了。
擴展閱讀
[1] gef官方文檔,http://gef.readthedocs.io/en/master/
[2] gdb調試利器,http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/gdb.html
[3] gdb中應該知道的幾個調試方法,https://coolshell.cn/articles/3643.html
本文由看雪翻譯小組 ljcnaix 原創 轉載請註明來自看雪社區
ARM彙編 與 ARM GNU彙編 區別
ARM 彙編 與 ARM GNU彙編 區別:https://blog.csdn.net/tabactivity/article/details/90054443
一、ARM彙編開發的兩種的方式
ARM 彙編開發,有兩種開發方式,一種是使用 ARM 彙編,一種是使用 ARM GNU 彙編。兩種彙編開發,使用的彙編指令是完全一樣的,區別是宏指令,僞指令,僞操作不一樣。其實兩種開發方式的區別在於所使用的編譯工具不一樣。
對於 ARM 彙編,使用的是 ARM 公司開發的編譯器,而 ARM GNU 彙編,是使用 GNU 爲 ARM 指令集開發的編譯器,也就是arm-gcc。
二、ARM的編譯開發環境
兩種常用的 ARM 的編譯開發環境
-
DS5:ARM 提供的集成開發軟件。使用的是 ARM 提供的工具鏈進行程序編譯
-
GNU 開發環境: 由 GNU 的彙編器 as,交叉編譯器 gcc,和 鏈接器ld 等組成
三、僞操作,宏指令,僞指令
- 僞操作:ARM 彙編語言程序裏的一些特殊指令助記符,其作用主要是完成彙編程序做各種準備工作,在源程序進行彙編時由彙編程序處理,而不是在計算機運行期間由機器執行。如程序段的定義,就屬於僞操作。
- 宏指令:一段獨立的程序代碼,可插在源程序中,通過僞操作來定義。
- 僞指令:ARM 彙編語言程序裏的一些特殊指令助記符,不在處理器運行期間執行,在彙編時,被合適的ARM的機器指令代替,從而實現真正的指令操作。
四、ARM 彙編僞操作
僞操作 |
語法格式 |
作用 |
GBLA |
GBLA Varible |
聲明一個全局的算術變量,並將其初始化爲0 |
GBLL |
GBLL Varible |
聲明一個全局的邏輯變量,並將其初始化成{FALSE} |
GBLS |
GBLS Varible |
聲明一個全局的字符串變量,並將其初始化成空串 |
LCLA |
LCLA Varible |
聲明一個局部的算術變量,並將其初始化爲0 |
LCLL |
LCLL Varible |
聲明一個局部的邏輯變量,並將其初始化成{FALSE} |
LCLS |
LCLS Varible |
聲明一個局部的字符串變量,並將其初始化成空串 |
SETA |
SETA Varible expr |
給一個全局或局部算術變量賦值 |
SETL |
SETL Varible expr |
給一個全局或局部邏輯變量賦值 |
SETS |
SETS Varible expr |
給一個全局或局部字符串變量賦值 |
RLIST |
name LIST {list of registers} |
爲一個通用寄存器列表定義名稱 |
CN |
name CN expr |
爲一個協處理器的寄存器定義名稱 |
CP |
name CP expr |
爲一個協處理器定義名稱 |
DN/SN |
name DN/SN expr |
DN/SN爲一個雙精度/單精度的VFP寄存器定義名稱 |
FN |
name FN expr |
爲一個FPA浮點寄存器定義名稱 |
LTORG |
LTONG |
聲明一個數據緩衝池(文字池)的開始 |
MAP |
MAP expr {, base-register} |
定義一個結構化的內存表(storage map)的首地址 |
FIELD |
{label} FIELF expr |
定義一個結構化內存表中的數據域 |
SPACE |
{label} SPACE expr |
分配一塊連續內存單元,並用0初始化 |
DCB |
{label} DCB expr {,expr}.. |
分配一塊字節內存單元,並用expr初始化 |
DCD/ DCDU |
{label} DCD/DCDU expr {,expr}… |
分配一塊字內存單元, 並用expr初始化 |
DCDO |
{label} DCDO expr {,expr}… |
分配一塊字對齊的字內存單元, 並用expr初始化 |
DCFD/DCFDU |
{label} DCFD{U} fpliteral ,{,fpliteral}… |
爲雙精度的浮點數分配字對齊的內存單元 |
DCFS/DCFSU |
{label} DCFS{U} fpliteral ,{,fpliteral}… |
爲單精度的浮點數分配字對齊的內存單元 |
DCI |
{label} DCI expr, {expr}… |
ARM代碼分配一段字對齊的內存單元,填充expr(二進制指令碼),THUMB代碼中,分配一段半字對齊的半字內存單元。 |
DCQ/ DCQU |
{label} DCQ{U} {-} literal, {, {-} literal}… |
分配一段以雙字(8個字節)爲單位的內存 |
DCW/DCWU |
{label} DCW{U} {-} literal, {, {-} literal}… |
DCW用於分配一段半字對齊的半字內存單元 |
-
1、AREA:創建一段新的程序代碼或數據區。
格式 : AREA name, {,attr,} …
其中,name是程序段名, atrr是段名屬性
對於屬性,有以下一些:
CODE: 用於定義代碼段,默認爲是READONLY
DATA: 用於定於數據段,默認爲READWRITE
READONLY: 指定本段的內容只讀
READWRITE: 指定本段的內容可讀可寫
ALIGN: 指定對齊爲2次冪
COMMON: 定義通用的段。不包含任何用戶的代碼和數據。各源文件中同名的COMMON屬性段共享同一段存儲單元 - 2、ALIGN:指定對齊
ALIGN 4 表示4字節地址對齊
ALIGN 8 表示8字節地址對齊
注意:在AREA中使用和單獨使用ALIGN的區別,在於格式和對齊的計算不一樣。 - 3、ENTRY:指定彙編程序的入口。
一個程序至少有一個入口點,也可以有多個入口點,但是在一個源文件中,最多只能有一個ENTRY。
當多個源文件均有ENTRY時,由鏈接器指定程序真正的入口。 - 4、END:表示源程序的結束。所以彙編語言源文件必須以END結束,彙編器遇到END, 將結束編譯。
- 5、EXPORT
格式: EXPORT 標號 [,WEAK]
聲明一個全局標號,其他源文件可以使用這個標號。WEAK表示碰上其他同名標號時,其他標號優先。 -
6、IMPORT
格式: IMPORT 標號,[,WEAK]
表示該引用的標號在其他源文件中,單要在當前文件中引用。
WEAK表示找不到該標號時,也不報錯,一般該標號置爲0,如果是B 或BL指令用到該標號,該指令置爲nop。
該標號會加入到當前源文件的符號表中。 - 7、EXTERN:和 IMPORT 一樣,不同在於,如果當前文件沒有引用該標號,該標號不會加入到當前源文件的符號表中。
- 8、GET ( 或 INCLUDE ):將一個源文件包含到當前的源文件中
- 9、EQU:對一個常量標號賦值
格式: name EQU expression
其中: name符號名, expression寄存器相關或者程序相關的固定值
如:num EQU 2 ; 爲符號賦予數字2
EQU,等同於C語言中用#define定義一個常量 - 10、SPCAE:用於分配一片連續內存單元,並用0初始化。SPACE 可用 % 代替。
格式: {label} SPACE expr
label : 是一個標號, 可選
expr: 分配的內存字節數
如:stack SPACE 100 ; 分配100個字節內存單元,並用0初始化。標號stack是這片空間的起始地址 - 11、DCB:用於分配段字節內存單元,並用僞操作中的expr初始化。
格式: {label} DCB expr {,expr}
label: 是一個標號,可選
expr: 可以是-128~255的數值或者字符串
如:string DCB "HELLO" ;爲HELLO字符串分配空間, string是這塊空間的起始地址 - 12、DCD 及 DCDU:用於分配段字內存單元(分配的內存都是字對齊,DCDU並不嚴格字對齊),並用僞操作中的expr初始化。 DCD 可用 & 代替。
格式: {label} DCD expr, {,expr}
label: 是一個標號,可選,表示這塊內存單元的首地址
expr: 數字表達式或程序中的標號
如: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位的立即數或者一個地址值讀取到寄存器中。大範圍的地址讀取 |
NON |
NOP |
在彙編時,被替換成空操作 |
六、ARM GNU 編譯環境
僞操作 |
語法格式 |
作用 |
.byte |
.byte expr {,expr}… |
分配一段字節內存單元,並用expr初始化 |
.hword/.short |
.hword expr {,expr}… |
分配一段半字內存單元,並用expr初始化 |
.ascii |
.ascii expr {,expr}… |
定義字符串expr |
.asciz/.string |
.asciz expr {,expr}… |
定義字符串expr(會增加/0爲結束符) |
.floar/.single |
.float expr {,expr}… |
定義32bit IEEE浮點數expr |
.double |
.doubel expr {,expr}… |
定義64bit IEEE浮點數expr |
.word/.long/.int |
.word expr {,expr}… |
分配一段字內存單元,並用expr初始化 |
.fill |
.fill repeat {,size} {,value} |
分配一段字節內存單元,用sieze長度value填充repeat次 |
.zero |
.zero size |
分配一段字節內存單元,並用0填充內存 |
.space/.skip |
.space size, {,value} |
分配一段內存單元,用value將內存初始化 |
.section |
.section expr |
定義一個段 |
.text |
.text {subsection} |
代碼段, |
.data |
.data{subsection} |
數據段 |
.bss |
.bss{subsection} |
bss段 |
.cond 16/.thumb |
.code 16/.thumb |
表示之後的彙編指令使用THUMB指令集 |
.code 32/.arm |
.code 32/.arm |
表示之後的彙編指令使用ARM指令集 |
.end |
.end |
標記彙編文件的結束 |
.include |
.include "filename" |
將一個源文件包含到當前源文件中 |
.align/.balign |
.align {alignment} {,fill},{max} |
通過填充字節使當前位置滿足一定的對齊格式 |
七、兩種開發環境的區別
兩種開發環境下的彙編代碼,有較多不同的點,主要是符號及僞操作的不同。
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