彙編loop ARM彙編(二)

2021-10-12 08:16:49 字數 3569 閱讀 9970

前言:初學逆向 請多多指教

學習到的內容

1、arm的定址方式(一小部分)

2、arm的常用指令集

arm的定址方式

之前arm彙編(一)中的間接定址還有部分忘記寫了,今天補上

在對多暫存器及塊拷貝定址的時候,需要知道的如下內容:

基本使用的命令為:ldm/stm,然後還有關於在進行拷貝的時候的暫存器變化順序的四種方式:

ib (increment before operating) :位址先增後完成操作          

db (decrement before operating) :位址先減後完成操作

舉個如下指令:

ldmia  r0,     ;r1=[r0],r2=[r0+4],……r6=[r0+16]
這裡需要注意:

1、多暫存器語法表示:多暫存器用"{}"包含,連續暫存器使用"-"間隔,否則用","分隔;

2、ldmia 暫存器, 這裡是將左邊的暫存器位址+偏移值的位址的內容存放到右邊,從左到右的!

3、需要關注基址暫存器的變化方式,比如如上是ia,所以就是每次執行完了乙個arm指令之後,就需要將基址+4遞增,如果是ib的話則就是先+4遞增取值再賦值,所以順序不一樣結果也就不一樣

4、那麼stmia也是同樣的原理,唯一不同的就是 stm指令是將暫存器的值放置到記憶體位址中並且這裡遞增的是記憶體位址,而ldm是將記憶體位址的值放置到暫存器,並且遞增是暫存器

ldr r0,=0x87654321ldmia r0, // r0為基址 自增+4 的位址內容儲存到r1-r5暫存器中ldr r6,=0x12345678stmia r6, // r1-r5暫存器的值分別放入r6為基址 自增+4 的位址中
繼續來看堆疊定址

為什麼一般堆疊中 堆疊指標都是從高往低,因為這樣很比較安全,其中滿遞減的生成方式最為常見

stmfd  sp!,         ;入棧ldmfd  sp!,         ;彈出堆疊
需要注意的地方:

因為是堆疊(後進先出),所以在stmfd壓入的時候 也同樣是從右往左的順序來進行壓棧的,先壓入lr 然後再壓入r0-r7,但是ldrfd出棧的時候卻是順序是 從左往右,這個是需要注意的!

lr:代表r14暫存器

那麼只有通過stmfd才能對堆疊區的資料進行操作嗎?是否也可以通過塊拷貝的方式進行操作呢?

事實上,堆疊定址與多暫存器定址均可操作堆疊,在需要儲存特定某些暫存器值時,採用stm進行壓棧,採用ldm操作彈出堆疊;

儲存資料:s***b sp!, 彈出資料:ldmia sp!,
db指令與fd指令的最終含義相同,都是先遞減然後操作賦值

ia指令與fa指令的最終含義相同,都是先操作賦值然後遞增​

所以這裡也能通過塊拷貝的方式來進行實現堆疊操作

arm的常見指令集

ldr(load)和 str(store)指令型別:

常規的ldr 和 str指令:

ldr  r2,  [r5]   ;將r5為位址的儲存單元中資料載入至r2 str  r1,  [r0]  ;將r1暫存器的值儲存到 [r0]中
傳送資料型別:

ldrb  r3,  [r2],  #1  ;以r2為位址讀取一位元組資料至r3   然後r2=r2+1 strh  r1,  [r0, #2]!  ;二位元組傳送,傳送r1中低兩位元組資料 ;至r0+2為位址的儲存單元,r0更新
這裡也就是能體現定址的時候,前變址和後變址的概念了撒!

資料傳送指令:

mov  r1,  r0                     ;r1mov  r1,  r0,  lsl  #3      ; r1 r0*8 mvn  r0,  #0    ;立即數0取反傳送至r0,所以最終r0的值為-1
算數邏輯運算指令:

例1:64位整數加法

r0/r1與r2/r3分別存放兩個加數的低/高32位

r4/r5存放結果的低/高32位

adds r4,r0,r2 ;帶s字尾結果影響cpsr中的標誌位cadc r5,r1,r3 ;帶進製的加法,c標誌位參與運算,如果進製了 則加上進製的1 最終結果儲存到
例2:64位整數減

subs  r4,  r0,  r2 ;帶s字尾結果影響cpsr中的標誌位csbc  r5,  r1,  r3 ;帶進製的減法
例3:邏輯運算

and  r0,  r0,  #3  ;保持r0的0、1位,其餘清0orr r0,  r0,  #3  ;置位r0的0、1位,其餘不變eor  r0,  r0,  #3  ;反轉r0的0、1位,其餘不變bic   r0,  r0,  #3  ;清0 r0的0、1位,其餘不變
例4:比較指令

cmp  r1,  r0   ;r1-r0 如果r1-r0為0的話,則z標誌位為1cmn  r0,  #1  ;判斷r0的值是否為1的補碼(ffffffff),是則z置為1;  比如如果r0為-1的時候則z標誌位置位
cmn指令將運算元1暫存器減去運算元2的負值, 表示式也就是r0-(-1)

例5:測試指令

這裡的兩個測試指令:

tst會保留運算結果並且會影響cpsr的標誌位;

teq不會保留運算結果,但是會影響cpsr的標誌位

tst  r1,  #3   ;按位與,結果影響cpsr中的標誌位 ,並且保留運算結果teq  r1,  r2  ;按位異或,結果影響cpsr中的標誌位,但是不保留運算結果
例6:乘法指令

mul:32位乘法;

mla:三運算元乘法,將運算元1與運算元2相乘,結果加第三個運算元,存入目的暫存器;

使用:

mla,  rd,  rm, rs,  rn    ; rd=rm*rs+rn
規則:rd和rm不能是同一暫存器;

應用:形成兩個向量的標量積例程

r10為累加的結果,然後r11就是迴圈累加的次數,r8和r9暫存器的內容進行相乘 累加結果放到r10

mov r11,#20 /*計數即代表向量維度*/    mov r10,#0 /*初始化結果暫存器*/loop:    ldr r0,[r8],#4 /*讀取向量1指標*/    ldr r1,[r9],#4 /*讀取向量2指標*/    mla r10,r0,r1,r10    subs r11,r11,#1    bne loop

彙編實驗(二)

test 和 and 區別在於不改變op1 shr 如果要多移幾次 mov cl,4 shr dl,cl 判斷陣列裡正負數 並分開存放 assume cs code,ds data data segment m db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17...

彙編學習 二

如果要能編譯和執行asm檔案,則必須安裝masmsdk2.建立visual c 空白工程 3.新建asm檔案 這是網上摘錄的 mymain.asm.386 model flat,stdcall option casemap none include windows.inc include kerne...

彙編基礎 二

中斷處理 小寫轉大寫 rep movsb 字元輸出 int 10h assume cs code data segment db conversation 0 data ends code segment start mov ax,cs mov ds,ax mov si,offset capital...