都遵循gas汇编器的语法。
MOV RO, #1234
MOV R0, R1
LSL:逻辑左移,移位后寄存器空出的低位补0。
LSR:逻辑右移,移位后寄存器空出的高位补0。
ASR:算术右移,移位过程中,符号位保持不变,如果源操作数是正数,则空出的高位补0,否则补1.
ROR:循环右移,移位后移除的低位填入空出的高位。
RRX:带扩展的循环右移,操作数右移一位,移位空出的高位用C标志的值填充。
MOV R0, R1, LSL #2
R1寄存器左移两位赋值给R0,指令执行后,R0=R1*4。
LDR R0, [R1]
将R1寄存器的数值作为地址,取出此地址中的值赋给R0寄存器。
LDR R0, [R1, #-4]
寄存器R1的数组减去4作为地址,取出此地址中的值赋值给R0。
LDMIA R0, {R1, R2, R3, R4}
LDM是数据加载指令,指令的后缀IA表示每次执行完加载操作后R0寄存器的值自增1个字。指令执行后,R1=[R0],R2=[R0+#4],R3=[R0+#8],R4=[R0+#12]。
LDMFA/STMFA
LDMEA/STMEA
LDMFD/STMFD
LDMED/STMED
STMFD SP1, {R1-R7, LR}
将R1-R7,LR入栈,多用于保存子程序现场。
LDMFD SP1, {R1-R7, LR}
将数据出栈,放入R0-R7,LR寄存器,多用于恢复程序现场。
LDMIA/STMIA
LDMDA/STMDA
LDMIB/STMIB
LDMDB/STMDB
LDMIA R0!, {R1-R3}
从R0寄存器的存储单元中读取3个字到R1-R3寄存器中。
STMIA R0!, {R1-R3}
存储在R1-R3寄存器的内容到R0指向ed存储单元。
LDMIA/LDMDA中I表示Increasing,D表示decreasing,A表示After,B表示Before。
BL NEXT
...
NEXT:
...
BL NEXT是跳到NEXT标号处执行,这里的BL就是采用相对寻址,标号NEXT是偏移量。
定义load.s文件如下:
.data;//数据段 .balign 4 /* 四个字节对齐 */ myvar1: /* 定义变量myvar1 */ .word 3 /* 值为'3' */ .balign 4 /* 四个字节对齐 */ myvar2: /* 定义变量myvar2 */ .word 4 /* 值为'4' */ .text /* -- 代码段*/ .balign 4 /* 四个字节对齐 */ .global main main: ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */ ldr r1, [r1] /* r1 ← *r1 */ ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */ ldr r2, [r2] /* r2 ← *r2 */ add r0, r1, r2 /* r0 ← r1 + r2 */ bx lr /* 数据地址 */ addr_of_myvar1 : .word myvar1;//在链接的时候最后确认myvar1的地址 addr_of_myvar2 : .word myvar2;//在链接的时候最后确认myvar2的地址 复制代码
编译:
as -g -o load.o load.s
gcc -o load load.o
源码如下:
.data;//数据段 .balign 4 /* 四个字节对齐 */ myvar1: /* 定义变量myvar1 */ .word 0 /* 值为'0' */ .balign 4 /* 四个字节对齐 */ myvar2: /* 定义变量myvar2 */ .word 0 /* 值为'0' */ .text /* -- 代码段*/ .balign 4 /* 四个字节对齐 */ .global main main: ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */ mov r3,#3 str r3,[r1]//将r3中值保持到[r1],就是myvar1值=3 ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */ mov r3,#4 ldr r3, [r2] /* r3 ← *r2 */ ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */ ldr r1,[r1];// r1=myvar1值 ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */ ldr r2, [r2] /* r2 ← *r2 ,就是r2=0*/ add r0, r1, r2 /* r0 ← r1 + r2 ,就是3+0=3*/ bx lr /* 数据地址 */ addr_of_myvar1 : .word myvar1;//在链接的时候最后确认myvar1的地址 addr_of_myvar2 : .word myvar2;//在链接的时候最后确认myvar2的地址 复制代码
as -g -o store.o store.s
gcc -o store store.o
实现了将,
执行验证;
#./store
#echo $?
结果一致。
.arch armv8-a .data;//数据段 .balign 4 /* 四个字节对齐 */ myvar1: /* 定义变量myvar1 */ .word 3 /* 值为'3' */ .balign 4 /* 四个字节对齐 */ myvar2: /* 定义变量myvar2 */ .word 4 /* 值为'4' */ .text /* -- 代码段*/ .balign 4 /* 四个字节对齐 */ .global main main: ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */ ldr r1, [r1] /* r1 ← *r1 */ ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */ ldr r2, [r2] /* r2 ← *r2 */ add r0, r1, r2 /* r0 ← r1 + r2 */ mov x8, 93 svc 0 /* 数据地址 */ addr_of_myvar1 : .word myvar1;//在链接的时候最后确认myvar1的地址 addr_of_myvar2 : .word myvar2;//在链接的时候最后确认myvar2的地址 复制代码
编译:
as -g -o load64.o load64.s
gcc -o load64 load64.o
.data;//数据段 .balign 4 /* 四个字节对齐 */ myvar1: /* 定义变量myvar1 */ .word 0 /* 值为'0' */ .balign 4 /* 四个字节对齐 */ myvar2: /* 定义变量myvar2 */ .word 0 /* 值为'0' */ .text /* -- 代码段*/ .balign 4 /* 四个字节对齐 */ .global main main: ldr x1, addr_of_myvar1 /* r1 ← &myvar1 */ mov x3,#3 str x3,[x1]//将r3中值保持到[r1],就是myvar1值=3 ldr x2, addr_of_myvar2 /* r2 ← &myvar2 */ mov x3,#4 ldr x3, [x2] /* r3 ← *r2 */ ldr x1, addr_of_myvar1 /* r1 ← &myvar1 */ ldr x1,[x1];// r1=myvar1值 ldr x2, addr_of_myvar2 /* r2 ← &myvar2 */ ldr x2, [x2] /* r2 ← *r2 ,就是r2=0*/ add x0, x1, x2 /* r0 ← r1 + r2 ,就是3+0=3*/ mov x8, 93 svc 0 /* 数据地址 */ addr_of_myvar1 : .dword myvar1;//在链接的时候最后确认myvar1的地址 addr_of_myvar2 : .dword myvar2;//在链接的时候最后确认myvar2的地址 复制代码
as -g -o store64.o store64.s
gcc -o store64 store64.o