b) Lệnh copy dữ liệu
Nhóm lệnh này có chức năng đọc/ghi dữ liệu giữa bộ nhớ và thanh ghi. Có ba nhóm:
- Đọc dữ liệu từ bộ nhớ vào một thanh ghi: dữ liệu là byte, word (32bit) hay half-word (16bit)
- Đọc dữ liệu từ bộ nhớ vào nhiều thanh ghi: dữ liệu là words
- Đổi chỗ giá trị bộ nhớ - thanh ghi.
*) Đọc dữ liệu từ bộ nhớ cho một thanh ghi
32 bits:
Code: LDR r0, [r1] ; r0 := mem [r1]
STR r0, [r1] ; mem [r1] := r0
LDR r0,[r1, #4] ; r0 := mem[r1+4]
Giá trị chuyển dịch (như #4 trong vd trên) tối đa là +/- 4KB
8 bits:
Code: LDRB r0, [r1] ; r0 := mem [r1] [7:0]
STRB r0, [r1] ; mem [r1] [7:0] := r0
Cập nhật luôn giá trị thanh ghi địa chỉ:
Code: LDR r0, [r1], #4 ; r0 := mem[r1]
; r1 := r1 + 4
*) Đọc dữ liệu từ bộ nhớ vào nhiều thanh ghi:
Code: LDMIA r1,{r0, r2, r5} ; r0 := mem [r1]
; r2 := mem [r1+4]
; r5 := mem [r1+8]
Copy khối dữ liệu: trong các lệnh loại này, thanh ghi địa chỉ có thể tăng (Increase), giảm (Decrease) trước (Before) hoặc sau (After) khi dữ liệu được copy. Các lệnh này hay được dùng để quản lý stack.
Ví dụ: lệnh sau đây hay được dùng trong code prolog và code epilog của các hàm:
Code: STMFD SP!, {R4-R6,LR} ; Lưu giá trị R4, R5 & LR
; vào stack, trừ SP đi 4 x 4 = 0x10
SUB SP, SP, #0x24 ; Dành 0x24 bytes cho local vars
....
ADD SP, SP, #0x24 ; Phục hồi trạng thái stack
LDMFD SP!, {R4-R6,PC} ; Phục hồi thanh ghi R4, R6, trả về địa chỉ sau khi gọi BL vào thanh ghi PC (R15)
*) Đổi chỗ giá trị bộ nhớ - thanh ghi.
Code:
Ý nghĩa của lệnh này như sau: đọc giá trị từ bộ nhớ [Rn] vào thanh ghi Rd, sau đó ghi giá trị ở thanh ghi Rm vào [Rn].
c) Tập lệnh điều khiển, rẽ nhánh
Các lệnh rẽ nhánh thực hiện dựa trên trạng thái của các bit trong thanh ghi CPSR, bao gồm bit
N, S, C, V.
- Rẽ nhánh vô điều kiện:
Code:
- Rẽ nhánh có điều kiện:
Code: MOV r0, #0 ; initialize counter
LOOP: ...
ADD r0, r0, #1 ; increment counter
CMP r0, #10 ; compare with limit
BNE LOOP ; repeat if not equal
... ; else continue
Tổng kết các lệnh rẽ nhánh:
Code: Branch Interpretation Normal Uses
--------------------------------------------------------------
B Unconditional Always take this branch
BAL Always Always take this branch
BEQ Equal Comparison equal or zero result
BNE Not equal Comparison not equal or zero result
BPL Plus Result positive or zero
BMI Minus Result minus or negative
BCC Carry clear Arithmetic operation did not give carry-out
BLO Lower Unsigned comparison gave lower
BCS Carry set Arithmetic operation gave carry-out
BHS Higher or same Unsigned comparison gave higher or same
BVC Overflow clear Signed integer operation ; no overflow occurred
BVS Overflow set Signed integer operation ; overflow occurred
BGT Greater than Signed integer comparison gave greater than
BGE Greater or equal Signed integer comparison gave greater or equal
BLT Less than Signed integer comparison gave less than
BLE Less or equal Signed integer comparison gave less than or equal
BHI Higher Unsigned comparison gave highe
BLS Lower or same Unsigned comparison gave lower or same
Chú ý: các lệnh xử lý dữ liệu có thể bao gồm chức năng điều kiện:
Code: CMP r0, #5 ; if (r0 != 5) {
ADDNE r1, r1, r0 ; r1 := r1 + r0 - r2
SUBNE r1, r1, r2 ; }
Mã điều kiện:
Code: Opcode Mnemonic Interpretation Status flag state
[31:28] extension for execution
----------------------------------------------------------------------------------
0000 EQ Equal / equals zero Zset
0001 NE Not equal Zclear
0010 CS/HS Carry set / unsigned higher or same Cset
0011 CC/LO Carry clear / unsigned lower Cclear
0100 MI Minus / negative Nset
0101 Pl Plus / positive or zero Nclear
0110 VS Overflow Vset
0111 VC No overflow Vclear
1000 HI Unsigned higher Cset and Zclear
1001 LS Unsigned lower or same Cclear or Zset
1010 GE Signed greater than or equal N equals V
1011 LT Signed less than N is not Equal to V
1100 GT Signed greater than Z clear and N equals V
1101 LE Signed less than or equal Z set or Nis not equal to
1110 AL Always any
1111 NV Never (do not use!) none
Cơ chế gọi hàm của ARM : dùng thanh ghi
r14 (LR) lưu trữ địa chỉ lệnh kế tiếp sau lệnh
BL để quay trở về.
Code: BL SUBR ; branch to SUBR
... ; return to here
SUBR ... ; subroutine entry point
MOV pc, r14 ; return
Gọi hàm nhiều lớp (nested subroutines): thanh ghi R14 (LR) cần được cất vào stack trước khi gọi hàm.
Code: BL SUB1 ; branch to SUB1
...
SUB1 STMDA r13!, {r0-r2, r14} ; save regs
BL SUB2
...
LDMIB r13!, {r0-r2, pc} ; restore regs + return
SUB2 ...
MOV pc, r14 ; return
Chú ý: ARM không có phép toán
NOP (như x86). Để thay thế lệnh này, có thể dùng llệnh
MOV R0, R0 có opcode là
0000A0E1
Đến đây, với nội dung đã trình bày, bạn đã có thể đọc hiểu mã lệnh assembly của VXL ARM. Phần tiếp theo đề cập tới các công cụ debug, disassembler và editor hỗ trợ cho reverse engineering trên Windows Mobile.