Bảng sự thật, hai đầu vào, hai con số ở bên trái và một đầu ra, số bên phải:
HOẶC
a b c
0 0 0
0 1 1
1 0 1
1 1 1
hai đầu vào trái a và b đại diện cho bốn tổ hợp có thể của đầu vào, không ít hơn đó là danh sách.
Hãy xem xét 1 có nghĩa là đúng và 0 có nghĩa là sai. Và từ OR trong trường hợp này có nghĩa là nếu OR b là true thì c là true. Và như bạn thấy trong bảng, theo chiều ngang nếu a hoặc b là true thì c là true.
VÀ
a b c
0 0 0
0 1 0
1 0 0
1 1 1
Và có nghĩa là cả hai đều phải đúng nếu a AND b đều đúng thì c là đúng. Chỉ có một trường hợp tồn tại ở trên.
Bây giờ, hãy lấy hai byte 0x12 và 0x34 theo thập phân là 18 và 52 nhưng chúng tôi thực sự không quan tâm nhiều về số thập phân. chúng tôi quan tâm đến nhị phân 0x12 là 0b00010010 và 0x34 là 0b00110100. Các toán tử bitwise như AND và OR và XOR trong ngôn ngữ assembly có nghĩa là bạn lấy một bit từ mỗi toán hạng và cho kết quả trong cùng một vị trí bit. Nó không giống như thêm nơi bạn có những thứ như thế này cộng với bằng blah mang theo một.
vì vậy chúng tôi xếp hàng các bit
0b00010010 0x12
0b00110100 0x34
Vì vậy, nghiêng sidways đầu của bạn như bạn đang đi để có một vết cắn ra khỏi một taco tổ chức tại tay trái của bạn và hình dung bảng sự thật trên. Nếu chúng ta nhìn vào hai bit ở bên phải chúng là 0 và 0, hai bit tiếp theo là 1 và 0 và cứ thế tiếp tục.Vì vậy, nếu chúng ta muốn làm một hoạt động OR, nguyên tắc là nếu một trong hai a hoặc b là đúng thì c, kết quả, đúng
0b00010010
0b00110100
OR ==========
0b00110110
Trưởng nghiêng sang bên phải, ít nhất là bit quan trọng (các bit trong những cột trong số) 0 hoặc 0 = 0, không ai được đặt. cột tiếp theo (cột twos) 1 hoặc 0 = 1 ít nhất một là đúng. và vân vân nên
0x12 HOẶC 0x34 = 0x36
Trong lắp ráp cánh tay đó sẽ là
mov r0,#0x12
mov r1,#0x34
orr r2,r0,r1
sau hoặc r2 hoạt động sẽ giữ 0x36 giá trị.
Bây giờ cho phép và những con số
0b00010010
0b00110100
AND ==========
0b00010000
Nhớ bảng sự thật của chúng tôi và sự cai trị cả a và b phải là sự thật (1), chúng tôi nghiêng đầu của chúng tôi ở bên phải, 0 và 0 là 0, cả hai không đúng. và bằng cách kiểm tra chỉ có một cột có cả hai đầu vào với cột 1, cột 16. này lá chúng tôi với 0x12 VÀ 0x34 = 0x10
Trong lắp ráp cánh tay đó sẽ là
mov r0,#0x12
mov r1,#0x34
and r2,r0,r1
Bây giờ chúng ta có được sự hướng dẫn BIC. Viết tắt của bitwise rõ ràng, mà hy vọng sẽ có ý nghĩa trong một chút. Bic trên cánh tay là một anded với không b. Không phải là một bảng sự thật, nhưng chỉ có một đầu vào và một đầu ra
KHÔNG
a c
0 1
1 0
Với chỉ một đầu vào chúng ta chỉ có hai sự lựa chọn 0 và 1, 1 là đúng 0 là sai. KHÔNG có nghĩa là nếu không thì c là đúng. khi a không đúng c là đúng, khi a đúng là c không đúng. Về cơ bản nó đảo ngược.
gì bic làm là có hai đầu vào a và b, hoạt động là c = a AND (NOT b) vì vậy các bảng sự thật cho rằng sẽ là:
một AND (NOT b)
a b c
0 1 0
0 0 0
1 1 0
1 0 1
Tôi bắt đầu với bảng chân lý AND sau đó NOTted bit b, trong đó b là 0 trong bảng AND true, tôi đã đặt nó ở vị trí thứ 1 trong đó b là 1 trong bảng AND và tôi đã tạo thành 0.
Vì vậy, hoạt động của xe đạp trên 0x12 và 0x34 là
0b00010010
0b00110100
BIC ==========
0b00000010
Tại sao nó được gọi là hơi rõ ràng? Hiểu rằng làm cho nó dễ sử dụng hơn nhiều. Nếu bạn nhìn vào bảng sự thật và suy nghĩ về các đầu vào đầu tiên và thứ hai. Trường hợp thứ hai, b, đầu vào là 1 đầu ra là 0. trong đó đầu vào thứ hai, b, là 0, đầu ra là chính nó chưa được sửa đổi. Vậy bảng chân lý hoặc hoạt động đang làm gì là nói bất cứ nơi nào b được thiết lập rõ ràng hoặc bằng không những bit đó trong A. Vì vậy, nếu tôi có số 0x1234 và tôi muốn không có 8 bit thấp hơn, tôi sẽ BIC với 0x00FF. Và câu hỏi tiếp theo của bạn là tại sao không và với 0xFF00? (phân tích bảng sự thật AND và thấy rằng bất cứ nơi nào b là 1 bạn giữ giá trị như là, và bất cứ nơi nào b là một 0 bạn không đầu ra). ARM sử dụng thanh ghi 32 bit và một bộ lệnh 32 bit cố định, ít nhất là theo truyền thống.Hướng dẫn ngay lập tức
mov r0,#0x12
Trong tay được giới hạn ở 8 bit khác 0 được dịch chuyển ở bất kỳ vị trí nào trong số, sẽ được dịch chuyển một chút. Vì vậy, nếu tôi đã có 0x12345678 giá trị và muốn không ra 8 bit thấp hơn tôi có thể làm điều này
; assume r0 already has 0x12345678
bic r0,r0,#0xFF
hoặc
; assume r0 already has 0x12345678
mov r1,#0xFF000000
orr r1,r1,#0x00FF0000
orr r1,r1,#0x0000FF00
;r1 now contains the value 0xFFFFFF00
and r0,r0,r1
hoặc
; assume r0 already contains 0x12345678
ldr r1,my_byte_mask
and r0,r0,r1
my_byte_mask: .word 0xFFFFFF00
mà không phải là khủng khiếp, so với sử dụng một di chuyển và hai orrs, nhưng vẫn đốt cháy nhiều chu kỳ đồng hồ hơn so với giải pháp bic vì bạn ghi thêm chu kỳ bộ nhớ đọc my_byte_mask từ ram, có thể mất một lúc.
hoặc
; assume r0 already contains 0x12345678
mvn r1,#0xFF
and r0,r0,r1
này cuối cùng là không phải là một compromize xấu. lưu ý rằng mvn trong tài liệu cánh tay là bitwise không ngay lập tức, có nghĩa là rx = NOT (ngay lập tức). Ngay lập tức ở đây là 0xFF. NOT (0xFF) có nghĩa là đảo ngược tất cả các bit, nó là một thanh ghi 32 bit chúng ta sẽ có nghĩa là 0xFFFFFF00 là kết quả của NOT (0xFF) và đó là những gì thanh ghi r1 nhận được, trước khi thực hiện và. Vì vậy, đó là lý do tại sao bic có một vị trí trong bộ hướng dẫn ARM, bởi vì đôi khi phải mất ít hướng dẫn hơn hoặc chu kỳ đồng hồ để mặt nạ (mask = AND được sử dụng để thực hiện một số bit 0) bằng cách sử dụng lệnh bic thay vì và chỉ dẫn.
Tôi đã sử dụng mặt nạ từ làm khái niệm để tạo bit trong một số không để những người khác một mình. orring có thể được coi là làm bit trong một số trong khi để lại những người khác một mình, nếu bạn nhìn vào bảng chân lý OR bất kỳ thời gian b là 1 thì c là 1. Vì vậy, 0x12345678 HOẶC 0x000000FF kết quả trong 0x123456FF các bit trong lần thứ hai toán hạng được đặt. Vâng, cũng đúng là bất cứ khi nào a được đặt trong bảng true OR thì đầu ra được thiết lập, nhưng rất nhiều thời gian khi bạn sử dụng các phép toán bitwise này, bạn có một toán hạng mà bạn muốn thực hiện, thiết lập một số bit nhất định đến một mà không sửa đổi phần còn lại hoặc thiết lập một số bit nhất định bằng không mà không sửa đổi phần còn lại hoặc bạn muốn không phải tất cả các bit trừ một số bit nhất định. Khi được sử dụng theo cách đó, bạn có một toán hạng sắp tới trong đó là những gì bạn muốn hoạt động và bạn tạo toán hạng thứ hai dựa trên những gì bạn muốn hiệu ứng tổng thể, ví dụ trong C nếu chúng ta muốn giữ chỉ số byte thấp hơn, chúng ta có thể có một tham số trong, một tham số ra chức năng:
unsigned int keep_lower_byte (unsigned int a)
{
return(a&(~0xFF));
}
~ có nghĩa là không nên ~ 0xFF, cho số 32 bit có nghĩa 0xFFFFFF00 sau đó & phương tiện AND, vì vậy chúng tôi trả lại một 0xFFFFFF00 &. a là toán hạng thực sự duy nhất đến và chúng ta phát minh toán hạng thứ hai dựa trên hoạt động mà chúng ta muốn làm ... Hầu hết các phép toán bitwise bạn có thể hoán đổi các toán hạng trong lệnh và mọi thứ đều ổn, hướng dẫn như bic của ARM mặc dù toán hạng là theo một thứ tự nhất định, giống như một phép trừ, bạn phải sử dụng đúng thứ tự các toán hạng.
Đang chuyển ... có hai loại, lô-gic và số học. hợp lý là dễ nhất và là những gì bạn nhận được khi bạn sử dụng >> hoặc < < trong C.
Bắt đầu với 0x12 là 0b00010010.Chuyển rằng ba địa điểm ở phía bên trái (0x12 < < 3) có nghĩa là
00010010 < our original number 0x12
0010010x < shift left one bit location
010010xx < shift left another bit location
10010xxx < shift left a third bit location
gì bit nhận được "chuyển trong" đến các địa điểm trống, x'es trên, tùy thuộc vào hoạt động. Đối với lập trình C nó luôn luôn là số không:
00010010 < our original number 0x12
00100100 < shift left one bit location
01001000 < shift left another bit location
10010000 < shift left a third bit location
Nhưng đôi khi (thường mỗi tập lệnh hỗ trợ xoay cũng như một sự thay đổi) có những cách khác để thay đổi và sự khác biệt phải làm với những gì bit bạn chuyển vào chỗ trống, và đôi khi các bit bạn chuyển ra khỏi cuối không luôn luôn chỉ biến mất đôi khi bạn tiết kiệm rằng trong một vị trí giữ bit đặc biệt.
Một số bộ chỉ có một thay đổi một chút ý nghĩa cho mỗi lệnh bạn lập trình bạn chỉ có thể dịch chuyển một bit, vì vậy ở trên sẽ là 3 hướng dẫn, mỗi lần một bit. Các bộ hướng dẫn khác, như cánh tay, cho phép bạn có một lệnh duy nhất và bạn chỉ định trong lệnh có bao nhiêu bit bạn muốn dịch chuyển theo hướng đó. do đó, một sự thay đổi trái của ba
mov r0,#0x12
mov r3,r0,lsl#3 ; shift the contents of r0 3 bits to the left and store in r3
độ khác nhau này về những gì bạn chuyển trong được thể hiện giữa LSR và ASR, logic thay đổi ngay và số học dịch phải (bạn sẽ thấy rằng không có asl, thay đổi số học trái vì đó làm cho không có ý nghĩa, một số nhà lắp ráp sẽ cho phép bạn sử dụng một lệnh asl nhưng mã hóa nó như là một lsl).
Một sự thay đổi LOGIC phải:
00010010 - our original number 0x12
x0001001 - shifted right one bit
xx000100 - shifted right another bit
xxx00010 - shifted right another bit
Như với C có một phiên bản mà thay đổi trong số không, đó là sự thay đổi logic đúng, thay đổi trong số không
00010010 - our original number 0x12
00001001 - shifted right one bit
00000100 - shifted right another bit
00000010 - shifted right another bit
toán số học chuyển phương tiện ngay giữ gìn "bit dấu" bit bit dấu là gì? mà được vào twos bổ sung số mà bạn cũng cần phải tìm hiểu nếu bạn có không. Về cơ bản, nếu bạn xem xét mẫu/giá trị bit là số bổ sung twos thì bit quan trọng nhất, bit ở bên trái, là bit dấu. nếu nó bằng 0 thì số dương và 1 số âm. Bạn có thể nhận thấy rằng một sự dịch chuyển sang trái bằng một bit giống như nhân với 2 và quyền dịch chuyển là giống như chia cho 2. 0x12 >> 1 = 0x9, 18 >> 1 = 9 nhưng nếu chúng ta thay đổi một trừ 2 sang bên phải, trừ hai là 0xFE bằng cách sử dụng byte hoặc 0b11111110. sử dụng cách dịch chuyển logic hợp lý kiểu C phải 0xFE >> 1 = 0x7F hoặc bằng số thập phân -2 >> 1 = 0x127. Chúng ta không thể giải quyết mà trong C trong một hoạt động đơn lẻ, không may, nhưng trong lắp ráp chúng ta có thể sử dụng một sự thay đổi số học, giả sử tập lệnh của bạn có một, mà cánh tay không
shift toán số học đúng
s1100100 - our starting value s is the sign bit whatever that is 0 or 1
ss110010 - one shift right
sss11001 - another shift right
ssss1100 - another shift right
Vì vậy, nếu dấu chút s là 0 khi chúng tôi bắt đầu, nếu số lượng là 01.100.100 sau đó
01100100 - our starting value
00110010 - one shift right
00011001 - another shift right
00001100 - another shift right
nhưng nếu đó là bit dấu đã một
11100100 - our starting value
11110010 - one shift right
11111001 - another shift right
11111100 - another shift right
Và chúng ta có thể giải quyết vấn 0xFE chuyển ngay một:
11111110 - 0xFE a minus 2 in twos complement for a byte
11111111 - shifted right one
như vậy trong mã giả 0xFE ASR 1 = 0xFF, -2 ASR 1 = -1.-2 chia cho 2 = -1
Điều cuối cùng bạn cần tự mình đọc phải làm với quay và/hoặc điều gì xảy ra với bit bị dịch chuyển khỏi đầu. một sự thay đổi quyền lsbit được chuyển "off the end" của số như khối được trượt của một bảng và một trong đó rơi ra có thể chỉ đi vào "bit xô" (ether, trời hay địa ngục, một trong những nơi mà bit đi chết khi họ biến mất khỏi thế giới này). Nhưng một số hướng dẫn trong một số bộ hướng dẫn sẽ mất bit đó được chuyển đi và đặt nó trong cờ Carry (đọc lên trên cộng và trừ), không phải vì nó là một carry nhất thiết nhưng vì có bit trạng thái trong alu và bit Carry là một trong những kinda có ý nghĩa. Bây giờ quay vòng là gì, cho phép bạn nói rằng bạn có bộ xử lý 8 bit và bạn xoay một bit, bit rơi xuống vùng cuối cùng trong bit Carry, AND sự dịch chuyển bit ở phía bên kia là những gì nằm trong bit mang trước khi hoạt động. Về cơ bản nó là ghế âm nhạc, các bit đang đi bộ xung quanh ghế với một người đứng bên trái, người đứng là bit mang theo, những người trong ghế là những bit trong sổ đăng ký. Tại sao điều này hữu ích? cho phép nói rằng chúng tôi đã có một bộ xử lý 8 bit như Atmel AVR ví dụ nhưng muốn làm một sự thay đổi 64 bit. 64 bit mất 8, 8 bit, đăng ký, nói rằng tôi có số 64 bit của tôi trong 8 thanh ghi và tôi muốn làm một sự thay đổi 64 bit còn lại một chút. Tôi sẽ bắt đầu với byte ít quan trọng nhất và làm một lsl mà thay đổi một số không trong nhưng bit chuyển ra đi vào bit mang. sau đó byte quan trọng nhất tiếp theo tôi làm một rol, xoay trái một chút, bit đến là bit đi ra khỏi byte trước và bit đi ra ngoài để mang theo bit. Tôi lặp lại các hướng dẫn rol cho các byte khác, nhìn vào một sự thay đổi 16 bit:
00100010 z0001000 - our original number
00100010 z 0001000 - lsl the least significant byte, the ms bit z is in carry
0100010z 00010000 - rotate left the most significant byte pulling the z bit from carry
00100010z0001000 - if it had been a 16 bit register
0100010z00010000 - a logical shift left on a 16 bit with a zero coming in on the left
đó là những gì mà quay được cho và đó là lý do tại sao hướng dẫn lắp ráp phiền để cho bạn biết những gì cờ được sửa đổi khi bạn thực hiện một hoạt động logic.
Wow, câu trả lời của bạn đã gây ấn tượng với tôi! –
Đây là một câu trả lời thực sự tốt! Chúng tôi có thể yêu cầu quản trị viên lưu mật khẩu này không? – 71GA
@old_timer Bạn có thể biết tại sao tôi nhận được yêu cầu đăng ký chưa thay đổi - bic r0, r0, # 0x3 trong khi biên dịch cho Thumb khi tôi sử dụng cú pháp BIC của bạn? Đây có phải là lỗi từ năm 2007 không? https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34436 – 71GA