arm64


(1)PC是程序計數器,存儲將要執行的指令地址
(2)LR是鏈接寄存器,是ARM處理器中一個有特殊用途的寄存器,當調用函數時,返回地址即PC的值被保存到LR中(mov lr,pc)。
(3)IR是指令寄存器,用來保存當前正在執行的一條指令。當執行一條指令時,先把它從內存取到數據寄存器(DR)中,然后再傳送至IR。

 

mov   r1, #0x53000000   //立即數尋址方式
立即數要求以“#”作前綴,對於十六進制的數,還要求在#后面加上0x或者&。0x大家很好理解。

STR是比較重要的指令了,跟它對應的是LDR。ARM指令集是加載/存儲型的,也就是說它只處理在寄存器中的數據。那么對於系統存儲器的訪問就經常用到STR和LDR了。STR是把寄存器上的數據傳輸到指定地址的存儲器上。LDR就是把數據從存儲器傳輸到寄存器上。

ARM有兩種跳轉方式。
(1) mov pc <跳轉地址〉
 這種向程序計數器PC直接寫跳轉地址,能在4GB連續空間內任意跳轉。
(2)通過 B BL BLX BX 可以完成在當前指令向前或者向后32MB的地址空間的跳轉(為什么是32MB呢?寄存器是32位的,此時的值是24位有符號數,所以32MB)。
B是最簡單的跳轉指令。要注意的是,跳轉指令的實際值不是絕對地址,而是相對地址——是相對當前PC值的一個偏移量,它的值由匯編器計算得出。
BL非常常用。它在跳轉之前會在寄存器LR中保存PC的當前內容。BL的經典用法如下:
       bl NEXT   ; 跳轉到NEXT
       ……
    NEXT
       ……
       mov pc, lr    ; 從子程序返回。

 

在ARM架構下,  數據從內存到CPU之間的移動只能通過LDR/STR指令來完成.  而MOV只能在寄存器之間移動數據,或者把立即數移動到寄存器中

csel w0, w2, w0, gt
csel根據后面的條件決定如何賦值,如果是GT,則w0=w2,否則w0 = w0。

 

LDR  R0, [R1] 
這條指令的意思是,將R1中的值作為地址,將地址里面存的值復制給寄存器R0
STR R1,[R0]
這條指令的意思是,將R1里面的值,復制到以R0里面的值作為地址的內存里面。

 


 
typedef struct Person {
   int id;
   int age;
   char name[10];
   int sex;
} CPerson;



int getId(CPerson person) {
    return person.id;
}

int getAge(CPerson person) {
    return person.age;
}

int getSex(CPerson person) {
    return person.sex;
}

int run(CPerson person, int age) {
   if (age<7) {
       return 0xffff;
   } else if (age < 13) {
       return age +1;
   } else {
       age = getAge(person);
       return age;
   }
}

int run_1(int x) {
    if (x >15) {
        return 0xffff;
    } else {
        return 0x111;
    }
}

void test() {
    CPerson person ={12, 10, "cm", 1};
    run(person, 10);
}
mutian@mutian:~/share/test/test$ cp ~/workspace/NDK/libs/arm64-v8a/libhello-jni.so .
mutian@mutian:~/share/test/test$ ~/soft/android-ndk-r10e/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -S -D libhello-jni.so   > x.log

000000000000063c <getId>:
 63c:   b9400000        ldr     w0, [x0]
 640:   d65f03c0        ret

0000000000000644 <getAge>:
 644:   b9400400        ldr     w0, [x0,#4]
 648:   d65f03c0        ret

000000000000064c <getSex>:
 // 這個方法是全局方法,所以x0是第一個參數
 // 結構體按最大的數據類型進行字節對齊,所以sex偏移值是20,而不是18
 // 返回值存放在w0中, w0是x0的低32位
 64c:   b9401400        ldr     w0, [x0,#20]
 650:   d65f03c0        ret

0000000000000654 <run>:
 // stack 擴大30 每個方法調用前就已經知道,這個方法需要多大stack
 654:   d100c3ff        sub     sp, sp, #0x30
 //cmp指令 w1 - 0x6 結果不存儲 只更改狀態寄存器CPSR中的條件標志位
 658:   7100183f        cmp     w1, #0x6
 65c:   aa0003e2        mov     x2, x0
 660:   529fffe0        mov     w0, #0xffff                     // #65535
 664:   f90003fe        str     x30, [sp]
 668:   5400008c        b.gt    678 <run+0x24>
 66c:   f94003fe        ldr     x30, [sp]
 670:   9100c3ff        add     sp, sp, #0x30
 674:   d65f03c0        ret
 678:   7100303f        cmp     w1, #0xc
 67c:   11000420        add     w0, w1, #0x1
 680:   54ffff6d        b.le    66c <run+0x18>
 684:   a9401444        ldp     x4, x5, [x2]
 688:   f9400841        ldr     x1, [x2,#16]
 68c:   910043e0        add     x0, sp, #0x10
 690:   f90013e1        str     x1, [sp,#32]
 694:   a90117e4        stp     x4, x5, [sp,#16]
 698:   97ffffeb        bl      644 <getAge>
 69c:   f94003fe        ldr     x30, [sp]
 6a0:   9100c3ff        add     sp, sp, #0x30
 6a4:   d65f03c0        ret

00000000000006a8 <run_1>:
 6a8:   71003c1f        cmp     w0, #0xf
 6ac:   529fffe1        mov     w1, #0xffff                     // #65535
 6b0:   52802220        mov     w0, #0x111                      // #273
 6b4:   1a80c020        csel    w0, w1, w0, gt
 6b8:   d65f03c0        ret

 

 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM