Nhóm các lệnh này điều khiển dữ liệu ở bên trong thanh ghi. Chúng bao gồm các lệnh số học, các lệnh lôgic, các lệnh so sánh và các lệnh nhân. Đa số các lệnh xử lý dữ liệu có thể xử lý các toán hạng thông qua bộ dịch trong CPU. Cấu trúc chung của các lệnh xử lý dữ liệu được mô tả trong Hình 3.8.
Hình 3.8: Cấu trúc chung của nhóm lệnh xử lý dữ liệu
3.6.1. Các lệnh số học
Các lệnh số học thực hiện các phép tính cộng hoặc trừ đối với các giá trị có dấu hay không dấu 32 bit như mô tả trong Bảng 3.20.
Vi xử lý lõi Cortex-M3 hỗ trợ các câu lệnh nhân 32 bit và nhân cộng dồn (MAC) cho kết quả 32 bit hay 64 bits và hỗ trợ giá trị có dấu hay không dấu như tổng hợp trong Bảng 3.21.
93
Bảng 3.20. Các lệnh thao tác số học
Câu lệnh Mô tả Thao tác
ADD Rd, Rn, Rm Rd = Rn + Rm Lệnh cộng ADD Rd, Rn, #immed Rd = Rn + #immed
ADC Rd, Rn, Rm Rd = Rn + Rn + carry Lệnh cộng với nhớ ADC Rd, #immed Rd = Rd + #immed +
carry
ADDW Rd, Rn, #immed Rd = Rn + #immed Lệnh cộng thanh ghi với giá trị trực tiếp 12 bit SUB Rd, Rn, Rm Rd = Rn – Rm Lệnh trừ
SUB Rd, #immed Rd = Rd - #immed SUB Rd, Rn, #immed Rd = Rn - #immed SBC Rd, Rn, immed Rd = Rn - #immed –
borrow
Lệnh trừ có mượn SBC Rd, Rn, Rm Rd = Rn – Rm –
borrow
SUBW Rd, Rn, #immed Rd = Rn - #immed Lệnh trừ có mượn với giá trị trực tiếp 12 bit
RSB Rd, Rn, #immed Rd = #immed – Rn Lệnh trừ đảo RSB Rd, Rn, Rm Rd = Rm – Rn
MUL Rd, Rn, Rm Rd = Rn * Rm Lệnh nhân (32 bit kết quả)
UDIV Rd, Rn, Rm Rd = Rn/Rm Lệnh chia SDIV Rd, Rn, Rm Rd = Rn/Rm
Bảng 3.21. Các lệnh nhân và nhân cộng dồn
Câu lệnh (Không cần hậu tố “S” )
Mô tả Thao tác
MLA Rd, Rn, Rm, Ra Rd = Ra + Rn *Rm Câu lệnh 32 bit, kết quả 32 bit
MLS Rd, Rn, Rm, Ra Rd = Ra – Rn*Rm Câu lệnh 32 bit, kết quả 32 bit
SMULL RdLo, RdHi, Rn, Rm
{RdHi, RdLo} = Rn * Rm
Câu lệnh 32 bit cho các giá trị có dấu, kết quả 64 bit
SMLA RdLo, RdHi, Rn, Rm
{RdHi, RdLo}
+=Rn*Rm UMULL RdLo, RdHi, Rn,
Rm
{RdHi, RdLo} = Rn*Rm
Câu lệnh 32 bit cho các giá trị không dấu, kết quả 64 bit
UMLAL RdLo, RdHi, Rn, Rm
{RdHi, RdLo}
+=Rn*Rm
94
Ví dụ 3.21 – Minh họa lệnh SUB PRE R0 = 0x00000000
R1 = 0x00000002 R2 = 0x00000001 SUB R0, R1, R2 POST R0 = 0x00000001 Ví dụ 3.22 – Sử dụng bộ dịch
Lập trình viên có thể sử dụng các giá trị sau khi được tiền xử lý bằng bộ dịch bên trong câu lệnh như sau:
PRE R0 = 0x00000000 R1 = 0x00000005
ADD R0, R1, R1, LSL#1 POST R0 = 0x0000000F
R1 = 0x00000005 3.6.2. Các lệnh lôgic
Vi xử lý lõi Cortex –M3 và Cortex – M4 hỗ trợ các lệnh lôgic như AND, OR, XOR, v.v. Giống như các lệnh số học, phiên bản 16 bit của các lệnh này tự động cập nhật thanh ghi APSR. Nếu hậu tố “S” không được chỉ ra, trình biên dịch sẽ tự động chuyển chúng thành các câu lệnh 32 bit. Các thao tác lôgic được trình bày trong Bảng 3.22.
Bảng 3.22. Các lệnh lôgic
Câu lệnh Mô tả Thao tác
AND Rd, Rn Rd = Rd & Rn Bitwise AND AND Rd, Rn, #immed Rd = Rn & immed
AND Rd, Rn, Rm Rd = Rn & Rm
ORR Rd, Rn Rd = Rd | Rn Bitwise OR ORR Rd, Rn, #immed Rd = Rn | #immed
ORR Rd, Rn, Rm Rd = Rn | Rm
BIC Rd, Rn Rd = Rd & (~Rn) Bit Clear BIC Rd, Rn #immed Rd = Rn & (~#immed)
BIC Rd, Rn, Rm Rd = Rn & (~Rm)
ORN Rd, Rn, #immed Rd = Rn | (~#immed) Bitwise OR NOT ORN Rd, Rn, Rm Rd = Rn | (~Rm)
EOR Rd, Rn Rd = Rd ^ Rn Bitwise Exclusive OR EOR Rd, Rn, #immed Rd = Rn | #immed
EOR Rd, Rn, Rm Rd = Rn | Rm
95
3.6.3. Các lệnh dịch và quay
Vi xử lý lõi Cortex – M3 hỗ trợ các câu lệnh dịch và quay bit đa dạng như mô tả trong Hình 3.9 và được tổng hợp trong Bảng 3.23.
Nếu hậu tố S được sử dụng, các câu lệnh quay và dịch bit này sẽ đồng thời cập nhật cờ Carry trong thanh ghi APSR. Nếu thao tác dịch hay quay dịch vị trí của thanh ghi đi một số bit, thì giá trị của cờ C sẽ là bit cuối cùng bị dịch khỏi thanh ghi đó:
Hình 3.9: Mô tả các quá trình dịch và quay bit trong thanh ghi
Bảng 3.23. Tổng hợp các lệnh dịch và quay
Câu lệnh Mô tả Thao tác
LSL Rd, Rs Rd = Rd << Rs Dịch trái lôgic LSL Rd, Rm, #imm Rd = Rm << #imm
LSR Rd, Rs Rd = Rd >> Rs Dịch phải lôgic LSR Rd, Rs Rd = Rm >> #imm
ASR Rd, Rs Rd = Rd >> Rs Dịch phải số học ASR Rd, Rm, #imm Rd = Rm >> #imm
ROR Rd, Rs Rd quay phải Rs bit Quay phải
96
Ví dụ 3.23 – Minh họa lệnh BIC PRE R1 = 0b1111
R2 = 0b0101 BIC R0, R1, R2 POST R0 = 0b1010 3.6.4. Các lệnh chuyển kiểu dữ liệu
Trong vi xử lý Cortex – M3, một số lệnh cho phép mở rộng dữ liệu có dấu hay không dấu, ví dụ, để chuyển đổi một giá trị từ 8-bit sang 32-bit, hay từ 16-bit sang 32-bit. Các lệnh chuyển đổi giá trị không dấu và có dấu được trình bày ở Bảng 3.24.
Bảng 3.24. Các lệnh mở rộng kiểu dữ liệu
Câu lệnh Mô tả Thao tác
SXTB Rd, Rm Rd = signed_extend (Rn[7:0])
Mở rộng dữ liệu byte sang half word, giữ dấu
SXTH Rd, Rm Rd = signed_extend (Rn[15:0])
Mở rộng half-word sang word, giữ dấu
UXTB Rd, Rm Rd = unsigned_extend (Rn[7:0])
Mở rộng byte sang word, không giữ dấu
UXTH Rd, Rm Rd = unsigned_extend (Rn[15:0])
Mở rộng half-word sang word
Dạng 32 bit của các câu lệnh này cho phép truy cập vào các thanh ghi bank cao, và quay các giá trị input trước khi thực hiện các thao tác mở rộng kiểu dữ liệu, như ở Bảng 3.25.
Bảng 3.25. Các lệnh mở rộng kiểu dữ liệu với thao tác quay
Câu lệnh Thao tác
SXTB Rd, Rm {, ROR #n}; n = 8/16/24
Mở rộng dữ liệu byte sang word, giữ dấu
SXTH Rd, Rm {, ROR #n}; n = 8/16/24
Mở rộng half-word sang word, giữ dấu UXTB Rd, Rm {, ROR #n}; n =
8/16/24
Mở rộng byte sang word, không giữ dấu
UXTH Rd, Rm {, ROR #n}; n = 8/16/24
Mở rộng half-word sang word, không giữ dấu
Các lệnh này rất hữu dụng trong việc chuyển đổi giữa các dạng dữ liệu. Các giá trị có dấu hay không dấu mở rộng có thể được thực hiện trong quá trình nạp dữ liệu từ bộ nhớ vào thanh ghi. Một nhóm lệnh khác cho phép đảo thứ tự byte dữ liệu
97
trong một thanh ghi hoạt động như mô tả trong Hình 3.10, được tổng hợp trong Bảng 3.26.
Bảng 3.26. Các câu lệnh đảo dữ liệu
Câu lệnh Mô tả Thao tác
REV Rd, Rn Rd = rev(Rn) Đảo thứ tự byte trong word REV16 Rd, Rn Rd = rev16(Rn) Đảo thứ tự byte trong mỗi
half-word
REVSH Rd, Rn Rd = revsh (Rn) Đảo thứ tự bytes ở half- word sau và mở rộng dấu
Hình 3.10: Mô tả các thao tác đảo dữ liệu
3.6.5. Các lệnh xử lý trường bit
Các lệnh xử lý trường bit được liệt kê trong Bảng 3.27. Lệnh BFC cho phép lật từ 1 cho đến 31 bits gần đó tại bất kì vị trí nào của thanh ghi. Cú pháp của câu lệnh được cho như sau:
BFC <Rd>, <#lsb>, <#width>
98
Bảng 3.27. Các lệnh thao tác với bit trong thanh ghi
Câu lệnh Thao tác
BFC Rd, #<lsb>, #<width> Clear trường bit trong thanh ghi BFI Rd, Rn, #<lsb>, #<width> Thêm bit vào trong thanh ghi CLZ Rd, Rm Đếm số 0 ở phía trước
RBIT Rd, Rn Đảo thứ tự bit trong thanh ghi
SBFX Rd, Rn, #<lsb>, #<width> Sao chép trường bit từ thanh ghi nguồn và mở rộng thành giá trị có dấu
UBFX Rd, Rn #<lsb>, #<width> Sao chép trường bit từ một thanh ghi nguồn
Ví dụ 3.24 – Sử dụng lệnh BFC LDR R0, =0x1234FFFF BFC R0, #4, #8
Kết quả thu được sẽ là R0 = 0x1234F00F.
BFI (Bit Field Insert) sẽ sao chép một số bit (1-31) từ thanh ghi này sang một thanh ghi khác.
Ví dụ 3.25 – Sử dụng lệnh BFI LDR R0, =0x12345678
LDR R1, =0x3355AACC
BFI R1, R0, #8, #16 ;Chèn R0[15:0] vào R1 [23:8]
Câu lệnh sẽ cho kết quả R1 = 0x335678CC.
Lệnh RBIT sẽ đảo thứ tự bit trong một từ. Lệnh này rất hiệu quả trong việc xử lý chuỗi dữ liệu khi giao tiếp truyền thông. Ví dụ, nếu R0 = 0xB4E10C23, giá trị bit 1011_0100_1110_0001_0000_1100_0010_0011, nếu ta thực hiện:
RBIT R0, R1
R0 khi đó sẽ có kết quả 0xC430872D (giá trị nhị phân:
1100_0100_0011_0000_1000_0111_0010_1101).