ARM 彙編基礎教程番外篇 ——配置實驗環境

 

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 程序的編譯運行

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

    sudo apt-get install gdb-multiarch

  • arm 程序的調試

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


 

 

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

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章