3. Instruction Set
Bây giờ chúng ta biết những gì ARM cung cấp bằng cách nhớ và sổ đăng ký, và các loại hướng dẫn thao tác them.This chương mô tả những hướng dẫn rất chi tiết.
Như đã giải thích ở chương trước, tất cả các lệnh ARM 32 bit dài. Dưới đây là một điển hình một:
10101011100101010010100111101011
May mắn thay, chúng tôi không cần phải viết chương trình ARM sử dụng mã như vậy. Thay vào đó chúng ta sử dụng ngôn ngữ lắp ráp. Chúng tôi đã nhìn thấy ở cuối Chương Một vài thuật nhớ ARM điển hình. Thông thường, việc nhớ mật được theo sau bởi một hoặc nhiều toán hạng được sử dụng để mô tả hoàn toàn hướng dẫn.
Một ví dụ dễ nhớ là ADD , cho 'thêm hai thanh ghi. Điều này một mình không nói lắp ráp mà đăng ký để thêm và nơi để đặt kết quả. Nếu phía bên tay trái và bên phải của việc bổ sung là R1 và R2 tương ứng, và kết quả là để đi trong R0, phần toán hạng sẽ được ghi R0, R1, R2. Vì vậy, các add hoàn chỉnh hướng dẫn, định dạng lắp ráp, sẽ là:
ADD R0, R1, R2; R0 = R1 + R2
Hầu hết các thuật nhớ ARM bao gồm ba chữ cái, ví dụ như SUB , MOV , STR , STM . Một số 'extras tùy chọn' có thể được thêm vào một chút thay đổi ảnh hưởng của các hướng dẫn, dẫn đến việc nhớ mật nhưADCNES và LỢN .
Các thuật nhớ và các định dạng toán hạng cho tất cả các hướng dẫn của ARM được mô tả chi tiết trong phần dưới đây. Ở giai đoạn này, chúng tôi không giải thích làm thế nào để tạo ra các chương trình, lắp ráp và chạy chúng. Có hai cách chính để lắp ráp các chương trình ARM - bằng cách sử dụng lắp ráp xây dựng trong để BBC BASIC, hoặc sử dụng một nhà lắp ráp chuyên dụng. Các phương pháp trước đây là thuận tiện hơn để thử nghiệm các chương trình ngắn, sau này để phát triển các dự án quy mô lớn. Chương Bốn bao gồm việc sử dụng lắp ráp BASIC.
3.1 Điều kiện mã
Tài sản của điều kiện thực hiện chung cho tất cả các hướng dẫn ARM, do đó đại diện của mình trong lắp ráp được mô tả trước các cú pháp của các hướng dẫn thực tế.
Như đã đề cập trong chương hai, có bốn bit của tình trạng mã hóa thành một từ lệnh. Điều này cho phép mười sáu điều kiện có thể. Nếu điều kiện cho các hướng dẫn hiện hành là đúng, thực hiện đi trước. Nếu tình trạng này không nắm giữ, các hướng dẫn được bỏ qua và kế tiếp thực hiện.
Những lá cờ kết quả được thay đổi chủ yếu bởi các hướng dẫn thao tác dữ liệu. Những hướng dẫn chỉ ảnh hưởng đến các cờ nếu bạn rõ ràng cho họ. Ví dụ, một MOV hướng dẫn mà các bản sao nội dung của một đăng ký khác. Không cờ bị ảnh hưởng. Tuy nhiên, các MOVS (di chuyển với S et) hướng dẫn bổ sung gây ra những lá cờ kết quả được thiết lập. Cách thức mà mỗi lệnh ảnh hưởng đến những lá cờ được mô tả dưới đây.
Để thực hiện một lệnh có điều kiện, một hậu tố hai chữ được thêm vào các ghi nhớ. Các hậu tố, và ý nghĩa của chúng, được liệt kê dưới đây.
AL Luôn
Một lệnh với hậu tố này luôn được thực thi. Để tiết kiệm phải gõ ' AL ' sau khi phần lớn các hướng dẫn mà là vô điều kiện, hậu tố có thể được bỏ qua trong trường hợp này. Như vậy ADDAL và ADD có nghĩa là cùng một điều: thêm vô điều kiện.
NV Chưa bao giờ
Tất cả các điều kiện ARM cũng có nghịch đảo của họ, do đó, đây là nghịch đảo của luôn. Bất kỳ hướng dẫn đến tình trạng này sẽ bị bỏ qua. hướng dẫn như vậy có thể được sử dụng để "đệm" hoặc có thể sử dụng một (rất) lượng nhỏ thời gian trong một chương trình.
EQ Equal
Tình trạng này là đúng nếu Z kết quả cờ (không) được thiết lập. Điều này có thể xảy ra sau khi một lệnh so sánh nơi các toán hạng đều bằng nhau, hoặc trong bất kỳ hướng dẫn dữ liệu đã nhận được một kết quả không thành đích.
NE Không bằng
Đây rõ ràng là đối diện của EQ , và là sự thật nếu cờ Z là xóa. Nếu Z được thiết lập, và hướng dẫn với các NE điều kiện sẽ không được thực thi.
VS tràn bộ
Tình trạng này là đúng sự thật, nếu kết quả cờ V (overflow) được thiết lập. Cộng, trừ và so sánh hướng dẫn ảnh hưởng đến lá cờ V.
VC tràn rõ ràng
Các đối diện với VS .
MI Minus
Hướng dẫn đến tình trạng này chỉ thực hiện nếu N (tiêu cực) cờ được thiết lập. Như một điều kiện sẽ xảy ra khi các hoạt động dữ liệu cuối cùng đã đưa ra một kết quả mà là tiêu cực. Đó là, cờ N phản ánh trạng thái của bit 31 của kết quả. (Tất cả các dữ liệu hoạt động làm việc trên số 32-bit).
PL Thêm
Đây là đối diện với MI điều kiện và hướng dẫn với các PL điều kiện sẽ chỉ thực hiện nếu cờ N là xóa.
Bốn điều kiện tiếp theo thường được sử dụng sau khi so sánh hai số không dấu. Nếu những con số được so sánh là n1 và n2, các điều kiện n1> = n2, n1 <n2, n1> n2 và n1 <= n2, theo thứ tự trình bày.
CS bộ Carry
Tình trạng này là đúng sự thật, nếu kết quả cờ C (thực hiện) được thiết lập. Lá cờ carry bị ảnh hưởng bởi hướng dẫn số học như Thanh , SUB và CMP . Nó cũng bị thay đổi bởi các hoạt động liên quan đến việc chuyển dịch hoặc quay của toán hạng (hướng dẫn thao tác dữ liệu).
Khi được sử dụng sau khi một lệnh so sánh, CS có thể được hiểu là "cao hơn hoặc cùng ', nơi mà các toán hạng được coi là con số 32-bit không dấu. Ví dụ, nếu toán hạng trái của CMP là 5 và tay phải toán hạng là 2, carry sẽ được thiết lập. Bạn có thể sử dụng HS thay vì CS cho tình trạng này.
CC Carry rõ ràng
Đây là điều kiện để nghịch đảo CS . Sau một so sánh, CC điều kiện có thể được hiểu là có nghĩa là 'thấp hơn', nơi mà các toán hạng được một lần nữa coi như là con số không dấu. Một từ đồng nghĩa với CC làLO .
HI cao
Tình trạng này là đúng nếu cờ C được thiết lập và cờ Z là sai. Sau một so sánh hoặc trừ, sự kết hợp này có thể được giải thích như là toán hạng bên tay trái là lớn hơn so với bàn tay phải một, nơi các toán hạng được coi là unsigned.
LS thấp hơn hoặc tương tự
Tình trạng này là đúng nếu cờ C được xóa hoặc cờ Z được thiết lập. Sau một so sánh hoặc trừ, sự kết hợp này có thể được giải thích như là toán hạng bên tay trái là ít hơn hoặc bằng tay phải một, nơi các toán hạng được coi là unsigned.
Bốn điều kiện tiếp theo có những cách hiểu tương tự như trước đây bốn, nhưng được sử dụng khi số ký đã được so sánh. Sự khác biệt là họ đưa vào tài khoản các trạng thái của V (overflow) cờ, trong khi những người không dấu thì không.
Một lần nữa, các mối quan hệ giữa hai con số đó sẽ gây ra tình trạng này là đúng là n1> = n2, n1 <n2, n1> n2, n1 <= n2.
GE Lớn hơn hoặc bằng
Điều này đúng nếu N là xóa và V là xóa, hoặc N được thiết lập và V được thiết lập.
LT Ít hơn
Đây là đối diện với GE và hướng dẫn với điều kiện này sẽ được thực thi nếu N được thiết lập và V là xóa, hoặc N là xóa và V được thiết lập.
GT Lớn hơn
Điều này cũng giống như GE , với việc bổ sung rằng lá cờ Z phải được dọn sạch quá.
LE Nhỏ hơn hoặc bằng
Điều này tương tự như LT , và cũng đúng khi cờ Z được thiết lập.
Lưu ý rằng mặc dù các điều kiện tham khảo số ký và unsigned, các hoạt động trên những con số giống hệt nhau bất kể loại. Những điều duy nhất mà thay đổi là những lá cờ sử dụng để xác định xem liệu hướng dẫn là phải thi hành hay không.
Những lá cờ có thể được thiết lập và xóa một cách rõ ràng bằng cách thực hiện các hoạt động trực tiếp trên R15, nơi chúng được lưu trữ.
3.2 Nhóm một - thao tác dữ liệu
Nhóm này chứa các hướng dẫn mà làm hầu hết các thao tác dữ liệu trong chương trình ARM. Các nhóm khác có liên quan với việc di chuyển dữ liệu giữa bộ xử lý và bộ nhớ, hoặc thay đổi dòng điều khiển.
Nhóm này bao gồm mười sáu hướng dẫn riêng biệt. Tất cả đều có một định dạng rất tương tự đối với các toán hạng họ mất và 'extras tùy chọn' với. Chúng ta sẽ mô tả chúng quát sử dụng ADD , sau đó cung cấp cho các hoạt động chi tiết của từng loại.
định dạng assembler
Thanh có định dạng sau:
ADD {cond} {S} <đích>, <LHS>, <RHS>
Các bộ phận trong dấu ngoặc nhọn là tùy chọn. Cond là một trong các mã điều kiện hai chữ được liệt kê ở trên. Nếu nó được bỏ qua, "luôn luôn" điều kiện AL được giả định. Các S , nếu có, làm theo hướng dẫn để ảnh hưởng đến cờ kết quả. Nếu không có S , không ai trong số những lá cờ sẽ được thay đổi. Ví dụ, nếu một lệnh ADDS É mang lại một kết quả là âm tính, sau đó cờ N sẽ được thiết lập. Tuy nhiên, chỉ cầnADD É sẽ không làm thay đổi N (hoặc bất kỳ lá cờ khác) bất kể kết quả.
Sau khi ghi nhớ là ba toán hạng. <ĐÍCH> là đích đến, và là số đăng ký mà kết quả của Thanh là được lưu trữ. Mặc dù lắp ráp là hài lòng với con số thực tế ở đây, ví dụ như 0 cho R0, nó nhận ra R0, R1, R2 vv để đứng cho các số đăng ký. Ngoài ra, bạn có thể xác định một tên cho một đăng ký và sử dụng để thay thế. Ví dụ, trong BBC BASIC bạn có thể nói: -
IAC = 0
nơi IAC là viết tắt của, nói, nguyên ắc. Sau đó, điều này có thể được sử dụng trong một lệnh: -
ADD IAC, IAC, # 1
Các toán hạng thứ hai là phía bên tay trái của hoạt động. Nói chung, nhóm một hướng dẫn hành động trên hai giá trị để cung cấp kết quả. Đây được gọi là bên tay trái và phải, ngụ ý rằng các hoạt động xác định bằng phương pháp nhớ sẽ được viết giữa chúng trong toán học. Ví dụ, hướng dẫn:
ADD R0, R1, R2
có R1 và R2 như bên tay trái và bên phải, và R0 là kết quả. Điều này giống như một bài tập như R0 = R1 + R2 trong BASIC, vì vậy các toán hạng đôi khi được cho là trong thứ tự phân công.
Các <LHS> toán hạng luôn là một số đăng ký, giống như đích. Các <RHS> hoặc có thể đăng ký một, hoặc một toán hạng ngay lập tức, hoặc đăng ký một dịch chuyển hoặc xoay. Nó là hình thức linh hoạt bên tay phải có thể mất trong đó cung cấp nhiều sức mạnh để các hướng dẫn.
Nếu <RHS> là một số đăng ký đơn giản, chúng ta có được hướng dẫn như là người đầu tiên ADD ví dụ trên. Trong trường hợp này, các nội dung của R1 và R2 được thêm vào (như đã ký kết, số 32-bit) và kết quả được lưu trong R0. Vì không có điều kiện sau khi hướng dẫn, các Thanh hướng dẫn sẽ luôn luôn được thực thi. Ngoài ra, vì không có S , cờ kết quả sẽ không bị ảnh hưởng.
Ba ví dụ dưới đây tất cả thực hiện cùng Thanh hoạt động (nếu điều kiện là đúng):
ADDNE R0, R0, R2
ADDS R0, R0, R2
ADDNES R0, R0, R2
ADDS R0, R0, R2
ADDNES R0, R0, R2
Họ tất cả các add R2 để R0. Việc đầu tiên có một NE điều kiện, do đó hướng dẫn sẽ chỉ được thực hiện nếu cờ Z là xóa. Nếu Z được thiết lập khi các lệnh được bắt gặp, nó được bỏ qua. Điều thứ hai là vô điều kiện, nhưng có S tùy chọn. Do đó những lá cờ N, Z, V và C sẽ được thay đổi để phản ánh kết quả. Các ví dụ cuối cùng có điều kiện và S , vì vậy nếu Z được xóa bỏ, Thanh sẽ xảy ra và những lá cờ thiết lập cho phù hợp. Nếu Z được thiết lập, Thanh sẽ bị bỏ qua và những lá cờ vẫn không thay đổi gì.
toán hạng ngay lập tức
Toán hạng ngay lập tức được viết như một # tiếp theo là một số. Ví dụ, để tăng R0, chúng ta sẽ sử dụng:
ADD R0, R0, # 1
Bây giờ, như chúng ta biết, một lệnh ARM có 32 bit, trong đó để mã hóa các loại hướng dẫn, điều kiện, toán hạng, vv Trong nhóm một hướng dẫn có mười hai bit có sẵn để mã hóa các toán hạng ngay lập tức.Mười hai bit nhị phân có thể đại diện cho các số trong phạm vi 0..4095, hoặc -2048 .. + 2047 nếu chúng ta đối xử với họ như đã ký kết.
Các nhà thiết kế của ARM đã quyết định không sử dụng 12 bit có sẵn cho họ cho toán hạng tức thời trong các cách rõ ràng chỉ đề cập đến. Hãy nhớ rằng một số các bit trạng thái được lưu trữ trong các bit 26..31 của R15. Nếu chúng ta muốn lưu trữ một giá trị tức thời có sử dụng một nhóm một hướng dẫn, không có cách nào chúng ta có thể sử dụng phương pháp số mười hai-bit đơn giản.
Để làm được việc này và các vấn đề liên quan, các toán hạng ngay lập tức được chia thành hai lĩnh vực, được gọi là các vị trí (bốn bit đầu) và giá trị (được lưu trữ ở phía dưới tám bit). Các giá trị là một số tám bit đại diện cho 256 tổ hợp có thể. Các vị trí là một lĩnh vực bốn bit mà quyết định nơi ở từ 32-bit, các giá trị nằm. Dưới đây là một sơ đồ chỉ cách các giá trị mười sáu vị trí xác định nơi các giá trị đi. Các bit của phần giá trị được hiển thị như là 0, 1, 2 vv
Cách mô tả này một cách ngắn gọn là để nói rằng giá trị được quay bằng 2 bit * Vị trí bên phải trong vòng từ 32-bit. Như bạn có thể nhìn thấy từ biểu đồ, khi vị trí = & 03, tất cả các bit trạng thái trong R15 có thể đạt được.
B31
|
b0
|
Pos
|
........................ 76543210
| & 00 | |
10 ........................ 765.432
| & 01 | |
3210 ........................ 7654
| & 02 | |
543.210 ........................ 76
| & 02 | |
76543210 ........................
| & 04 | |
..76543210 ......................
| & 05 | |
.... 76543210 ....................
| & 06 | |
...... 76543210 ..................
| & 07 | |
........ 76543210 ................
| & 08 | |
.......... 76543210 ..............
| & 09 | |
............ 76543210 ............
| & 0A | |
.............. 76543210 ..........
| & 0B | |
................ 76543210 ........
| & 0C | |
.................. 76543210 ......
| & 0D | |
.................... 76543210 ....
| & 0E | |
...................... 76543210 ..
| & 0F |
Mười sáu vị trí thay đổi ngay lập tức
Khi sử dụng các toán hạng ngay lập tức, bạn không cần phải ghi rõ số về vị trí và giá trị. Bạn chỉ cần cung cấp số bạn muốn, và lắp ráp cố gắng để tạo ra các lĩnh vực mười hai-bit thích hợp. Nếu bạn chỉ định một giá trị mà không thể được tạo ra, chẳng hạn như & 101 (mà sẽ yêu cầu một giá trị chín-bit), một lỗi được tạo ra. Các Thanh hướng dẫn dưới đây cho biết thêm 65.536 (& 1000) để R0:
ADD R0, R0, # & 1000
Để có được con số này, các nhà lắp ráp có thể sử dụng một giá trị vị trí của 8 và giá trị là 1, mặc dù các kết hợp khác cũng có thể được sử dụng.
toán hạng chuyển
Nếu <RHS> toán hạng là một đăng ký, nó có thể được chế tác theo nhiều cách khác nhau trước khi nó được sử dụng trong hướng dẫn. Các nội dung của đăng ký không thay đổi, chỉ là giá trị trao cho các ALU, như áp dụng cho hoạt động này (trừ khi đăng ký tương tự cũng được sử dụng như là kết quả, tất nhiên).
Các hoạt động cụ thể mà có thể được thực hiện trên <RHS> nhiều loại khác nhau của chuyển và luân chuyển. Số lượng bit mà đăng ký được chuyển hoặc xoay có thể được đưa ra như một số ngay lập tức, hoặc quy định trong một đợt đăng ký.
Thay đổi và quay được quy định như trái hoặc phải, hợp lý hoặc số học. Một sự thay đổi còn lại là một trong những nơi các bit, như được viết trên trang, được di chuyển bởi một hoặc nhiều bit bên trái, tức là vào cuối có ý nghĩa hơn. Zero-giá trị bit được chuyển vào ở bên phải và các bit ở bên trái bị mất, trừ các bit cuối cùng được chuyển ra, mà được lưu trữ trong lá cờ carry.
Thay đổi lại bằng n bit có hiệu quả nhân số 2 n , giả định rằng không có bit có ý nghĩa là 'mất' vào cuối đầu.
Một sự thay đổi đúng là theo hướng ngược lại, các bit di chuyển từ cuối có ý nghĩa hơn đối với các cấp thấp, hoặc từ trái sang phải trên trang. Một lần nữa các bit chuyển ra bị mất, trừ người cuối cùng được đưa vào thực hiện. Nếu dịch phải là hợp lý thì số không được chuyển vào đầu bên trái. Trong sự thay đổi số học, một bản sao của bit 31 (tức là bit dấu) được chuyển vào.
Thay đổi số học phải bằng n bit có hiệu quả chia số 2 n , làm tròn về phía trừ vô cực (như BASIC INT chức năng).
Một xoay giống như một sự thay đổi ngoại trừ các bit chuyển ở bên trái (bên phải) kết thúc là những người được ra khỏi bên phải (trái) kết thúc.
Dưới đây là các loại thay đổi và quay mà có thể được sử dụng:
LSL #n chuyển Logical trái ngay lập tức
n là số lượng các vị trí bit mà giá trị được thay đổi. Nó có giá trị 0..31. Một LSL bởi một chút có thể được hình dung như sau:
Sau n ca, n không bit đã được chuyển vào bên phải và các carry được thiết lập để bit 32-n của từ gốc.
Lưu ý rằng nếu không có sự thay đổi quy định sau khi <RHS> giá trị đăng ký, LSLÊ # 0 được sử dụng, không có tác dụng.
ASL #n Arithmetic chuyển trái ngay lập tức
Đây là một từ đồng nghĩa với LSL #n và có tác dụng giống hệt nhau.
LSR #n chuyển Logical phải ngay lập tức
n là số lượng các vị trí bit mà giá trị được thay đổi. Nó có giá trị 1..32. Một LSR bởi một chút được hiển thị dưới đây:
Sau n trong số này, n không bit đã được chuyển vào bên trái, và cờ carry được thiết lập để bit n-1 của từ gốc.
ASR #n Arithmetic chuyển phải ngay lập tức
n là số lượng các vị trí bit mà giá trị được thay đổi. Nó có giá trị 1..32. Một ASR bởi một chút được hiển thị dưới đây:
Nếu 'dấu hiệu' là giá trị ban đầu của bit 31 thì sau khi n ca, n 'dấu hiệu' bit đã được chuyển vào bên trái, và cờ carry được thiết lập để bit n-1 của từ gốc.
ROR #n Xoay phải ngay lập tức
n là số lượng các vị trí bit để xoay trong khoảng 1..31. Một bên phải xoay bởi một chút được hiển thị dưới đây:
Sau khi n các quay, bit n cũ là ở vị trí các bit 0; bit cũ (n-1) là trong bit 31 và trong cờ carry.
Lưu ý rằng một xoay trái của vị trí n là giống như một quyền xoay bằng (32-n). Cũng lưu ý rằng không có xoay đúng 32 bit. Các mã lệnh mà có thể làm điều này đã được dành riêng cho xoay đúng với mở rộng (xem dưới đây).
RRX Xoay bên phải một chút với mở rộng
Đây trường hợp đặc biệt xoay bên phải có một tác động hơi khác nhau từ quay bình thường. Không có số lượng; nó luôn luôn quay bởi một chút mà thôi. Các đại diện bằng hình ảnh của RRX là:
Các bit cũ 0 được chuyển vào thực hiện. Các nội dung cũ của carry được chuyển vào bit 31.
Lưu ý rằng không có tương đương RLX xoay. Tuy nhiên, tác dụng tương tự có thể thu được bằng cách sử dụng lệnh:
ADCS R0, R0, R0
Sau này, các carry sẽ chứa bit cũ 31 của R0, và bit 0 của R0 sẽ chứa các carry cờ cũ.
LSL RN chuyển Logical trái của một thanh ghi.
ASL chuyển Arithmetic rn trái của một thanh ghi.
LSR RN thay đổi logic đúng bởi một thanh ghi.
ASR rn thay đổi số học đúng bởi một thanh ghi.
ROR rn Xoay phải bởi một đăng ký
Nhóm này hoạt động giống như các nhóm thay đổi ngay lập tức, nhưng có số lượng từ nội dung của một đăng ký quy định thay vì một giá trị ngay lập tức. Chỉ byte thấp của thanh ghi được sử dụng, vì vậy số lượng thay đổi là trong khoảng 0..255. Tất nhiên, chỉ có số lượng trong phạm vi 0..32 có ích anyway.
Bây giờ chúng ta có cú pháp hoàn chỉnh của nhóm một hướng dẫn:
ADD {cond} {S} <đích>, <LHS>, <RHS>
nơi <ĐÍCH> và <LHS> được đăng ký, và <RHS> là:
# <giá trị> hoặc
<Reg> {, <shift>}
nơi <value> là một số ngay lập tức chuyển như đã giải thích ở trên, <reg> là một đăng ký và <shift> là:
<kiểu chuyển> # <shift count> hoặc <ca Loại> <reg> hoặc RRX
nơi <ca Loại> là LSL , ASL , LSR , ASR , ROR và <shift count> là trong phạm vi 0..32, tùy thuộc vào loại thay đổi.
Dưới đây là một ví dụ của Thanh hướng dẫn sử dụng chuyển toán hạng:
ADD R0, R0, R0, LSL # 1; R0 = R0 + 2 * R0 = 3 * R0
thiệu Hướng dẫn
Những điều nói trên áp dụng cho tất cả các nhóm một hướng dẫn. Bây giờ chúng ta liệt kê và giải thích các hoạt động cá nhân trong nhóm. Chúng có thể được chia thành hai phân nhóm: logic và số học.Những khác biệt trong cách thức mà những lá cờ kết quả bị ảnh hưởng (giả sử S là hiện diện trong ghi nhớ). Hướng dẫn số học thay đổi N, Z, V và C theo các kết quả của các phép cộng, trừ, vv
Hướng dẫn hợp lý ảnh hưởng đến N và Z theo các kết quả của các hoạt động, và C theo bất kỳ thay đổi hoặc quay đã xảy ra trong <RHS> . Ví dụ, hướng dẫn:
Ands R0, R1, R2, LSR # 1
sẽ thiết lập C từ bit 0 của R2. Toán hạng ngay lập tức nói chung sẽ rời khỏi carry không bị ảnh hưởng nếu giá trị vị trí là 0 (tức là một toán hạng trong phạm vi 0..255). Đối với các giá trị tức thời khác, trạng thái của C là khó dự đoán sau khi hướng dẫn, và nó có lẽ là tốt nhất không nên giả định bất cứ điều gì về tình trạng của các carry sau một hoạt động hợp lý trong đó sử dụng S tùy chọn và có một toán hạng ngay lập tức.
Tổng kết tình trạng của những lá cờ kết quả sau khi bất kỳ hoạt động hợp lý, nếu S tùy chọn không được đưa ra, thì không có sự thay đổi để những lá cờ. Nếu không thì:
- Nếu kết quả là âm tính (cắn 31 = 1), N được thiết lập, nếu không nó sẽ bị xóa.
- Nếu kết quả là số không, Z được thiết lập, nếu không nó sẽ bị xóa.
- Nếu <RHS> liên quan đến một sự thay đổi hoặc xoay, C được thiết lập từ này, nếu không nó không bị ảnh hưởng bởi các hoạt động.
- V là không bị ảnh hưởng
VÀ logic AND
Các VÀ hướng dẫn sản xuất các bit-khôn ngoan và toán hạng của nó. AND của hai bit là 1 chỉ khi cả hai bit là 1, như tóm tắt dưới đây:
<LHS> | <RHS> | <LHS> VÀ <RHS> |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Trong ARM và giảng dạy, hoạt động này được áp dụng cho tất cả 32 bit trong toán hạng. Đó là, bit 0 của <LHS> là VÀ ed với bit 0 của <RHS> và được lưu trữ trong bit 0 của <đích> , và như vậy.
Ví dụ:
Ands R0, R0, R5; Mask muốn bit sử dụng R5
VÀ R0, R0, # & DF; Chuyển đổi nhân vật để các trường hợp trên
VÀ R0, R0, # & DF; Chuyển đổi nhân vật để các trường hợp trên
BIC rõ ràng quy định bit
Các BIC hướng dẫn sản xuất các bit-khôn ngoan và của <LHS> và không <RHS> . Điều này có tác dụng làm sạch các <LHS> chút nếu <RHS> bit được thiết lập, và rời khỏi <LHS> chút không thay đổi gì khác.
<LHS> | <RHS> | KHÔNG <RHS> | <LHS> VÀ KHÔNG <RHS> |
0 | 0 | 1 | 0 |
0 | 1 | 0 | 0 |
1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 |
Ví dụ:
BIC R0, R0, R5, Zero, bit không mong muốn sử dụng R5
BIC R0, R0, # & 20; Chuyển đổi sang mũ bằng cách xóa bit 5
BIC R0, R0, # & 20; Chuyển đổi sang mũ bằng cách xóa bit 5
bit TST thử nghiệm
Các TST hướng dẫn thực hiện và hoạt động trên của nó <LHS> và <RHS> toán hạng. Kết quả là không lưu trữ bất cứ nơi nào, nhưng những lá cờ kết quả được quy định theo kết quả. Khi chỉ có hai toán hạng, định dạng của TST là:
TST <LHS>, <RHS>
Ngoài ra, như mục đích duy nhất của việc thực hiện một TST là để thiết lập cờ theo kết quả, các nhà lắp ráp giả định S có mặt cho dù bạn chỉ định hay không, tức là TST luôn ảnh hưởng đến các lá cờ.
Xem phần "Sử dụng R15 trong một nhóm hướng dẫn 'dưới đây.
Ví dụ:
TST R0, R5; Kiểm tra bit sử dụng r5, đặt cờ
TST R0, # & 20; Kiểm tra trường hợp của nhân vật trong R0
TST R0, # & 20; Kiểm tra trường hợp của nhân vật trong R0
Orr Logical OR
Các ORR hướng dẫn sản xuất các bit-khôn ngoan hay toán hạng của nó. Các OR của hai bit là 1 nếu một trong hai hoặc cả hai bit là 1, như tóm tắt dưới đây:
<LHS> | <RHS> | <LHS> OR <RHS> |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Trong ARM ORR giảng dạy, hoạt động này được áp dụng cho tất cả các bit trong toán hạng. Đó là, bit 0 của <LHS> được ORed với bit 0 của <RHS> và được lưu trữ trong bit 0 của <đích> , và như vậy. Hướng dẫn này thường được sử dụng để thiết lập bit cụ thể trong một đăng ký mà không ảnh hưởng đến người khác. Nó có thể được coi là một hoạt động bổ sung cho BIC .
Ví dụ:
ORRS R0, R0, R5; Set mong muốn bit sử dụng R5
ORR R0, R0, & 80000000; Set bit đầu R0
ORR R0, R0, & 80000000; Set bit đầu R0
EOR Logical độc quyền-OR
Các EOR hướng dẫn sản xuất các bit-wise độc quyền-OR toán hạng của nó. Các EOR của hai bit là 1 chỉ khi họ là khác nhau, như tóm tắt dưới đây:
<LHS> | <RHS> | <LHS> EOR <RHS> |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Trong ARM EOR giảng dạy, hoạt động này được áp dụng cho tất cả các bit trong toán hạng. Đó là, bit 0 của <LHS> được EORed với bit 0 của <RHS> và được lưu trữ trong bit 0 của <đích> , và như vậy. Các EORhướng dẫn thường được sử dụng để đảo ngược trạng thái của các bit nhất định của một đăng ký mà không ảnh hưởng đến phần còn lại.
Ví dụ:
EORS R0, R0, R5; Đảo ngược bit sử dụng R5, đặt cờ
EOR R0, R0, # 1; trạng thái của bit 0 "Toggle '
EOR R0, R0, # 1; trạng thái của bit 0 "Toggle '
TEQ thử nghiệm tương đương
Các TEQ hướng dẫn thực hiện các hoạt động EOR trên của nó <LHS> và <RHS> toán hạng. Kết quả là không lưu trữ bất cứ nơi nào, nhưng những lá cờ kết quả được quy định theo kết quả. Khi chỉ có hai toán hạng, định dạng của TEQ là:
TEQ <LHS>, <RHS>
Ngoài ra, như mục đích duy nhất của việc thực hiện một TEQ là để thiết lập cờ theo kết quả, các nhà lắp ráp giả định S có mặt cho dù bạn chỉ định hay không, tức là TEQ luôn ảnh hưởng đến các lá cờ.
Một sử dụng TEQ là để kiểm tra nếu hai toán hạng đều bình đẳng mà không ảnh hưởng đến trạng thái của lá cờ C, như CMP hướng dẫn không (xem dưới đây). Sau khi hoạt động như vậy, Z = 1 nếu các toán hạng đều bình đẳng, hoặc 0 nếu không. Ví dụ thứ hai sau đây minh họa điều này.
Xem phần "Sử dụng R15 trong một nhóm hướng dẫn 'dưới đây.
Ví dụ:
TEQ R0, R5; bit thử nghiệm sử dụng R5, đặt cờ
TEQ R0, # 0; Xem nếu R0 = 0.
TEQ R0, # 0; Xem nếu R0 = 0.
MOV Di chuyển giá trị
Các MOV hướng dẫn chuyển của nó <RHS> toán hạng vào sổ đăng ký theo quy định của <ĐÍCH> . Không có <LHS> quy định trong hướng dẫn, vì vậy định dạng lắp ráp là:
MOV <đích>, <RHS>
Ví dụ:
MOV R0, R0, LSL # 2; Multiply R0 bốn.
MOVS R0, R1; Đặt R1 R0, đặt cờ
MOV R1, # & 80; t R1 đến 128
MOVS R0, R1; Đặt R1 R0, đặt cờ
MOV R1, # & 80; t R1 đến 128
Mvn Di chuyển giá trị
Các MOV hướng dẫn chuyển giao logic NOT của nó <RHS> toán hạng vào sổ đăng ký theo quy định của <ĐÍCH> . Đảo ngược các <RHS> trước khi chuyển cho phép các toán hạng tiêu cực ngay lập tức được nạp.Không có <LHS> quy định trong hướng dẫn, vì vậy định dạng lắp ráp là:
Mvn <đích>, <RHS>
Nói chung, -n = NOT (n-1). Điều này có nghĩa rằng để tải một số tiêu cực, bạn trừ đi một từ giá trị tích cực của nó và sử dụng trong các mvn . Ví dụ, để tải số -128 bạn sẽ làm một mvn 127.
Ví dụ:
MVNS R0, R0; Đảo ngược tất cả các bit của R0, đặt cờ
mvn R0, # 0; t R0 để & FFFFFFFF, tức là -1
mvn R0, # 0; t R0 để & FFFFFFFF, tức là -1
Mô tả của các hướng dẫn số học theo. Dưới đây là một bản tóm tắt về cách cờ kết quả bị ảnh hưởng bởi những hướng dẫn này. Nếu S tùy chọn không được xác định, không có sự thay đổi diễn ra. Nếu không thì:
Nếu kết quả là âm tính (cắn 31 = 1), N được thiết lập, nếu không nó sẽ bị xóa.
Nếu kết quả là số không, Z được thiết lập, nếu không nó sẽ bị xóa.
Nếu các hoạt động tạo ra một carry, C được thiết lập, nếu không nó sẽ bị xóa.
Nếu các hoạt động tạo ra một tràn, V được thiết lập, nếu không nó sẽ bị xóa.
Lưu ý rằng nếu C = 1 sau một ADDS , hàm ý là một carry được tạo ra, ví dụ như việc bổ sung tràn vào chút 32. Điều này không có nghĩa là kết quả là sai. Ví dụ, thêm -1 đến 10 sẽ sản xuất như sau:
00000000000000000000000000001010 | |
+ | 11111111111111111111111111111111 |
00000000000000000000000000001001 | |
1 |
Tình trạng của carry sau một SUBS là đối diện rằng sau một ADDS . Nếu C = 1, không mượn được tạo ra trong quá trừ. Nếu C = 0, a mượn được yêu cầu. Lưu ý rằng theo định nghĩa này, vay = KHÔNG thực hiện, do đó, các bản tóm tắt của các quốc gia của các lá cờ trên là chính xác.
Định nghĩa chính xác của tình trạng tràn là exclusive- OR của mang từ bit 30 và 31 trong cộng hoặc trừ hoạt động. Điều này có nghĩa là trong thực tế là nếu cờ V được thiết lập, kết quả là quá lớn để vừa trong một từ 32-bit duy nhất. Trong trường hợp này, các dấu hiệu của kết quả sẽ là sai, mà là lý do tại sao các mã điều kiện ký kết có các trạng thái của V cờ vào tài khoản.
ADD Addition
Hướng dẫn này cho biết thêm <LHS> toán hạng cho <RHS> toán hạng, lưu trữ các kết quả trong <ĐÍCH> . Việc bổ sung là ba mươi hai bit đã ký hoạt động, mặc dù nếu các toán hạng được coi là con số không dấu, thì kết quả có thể được quá.
Ví dụ:
ADD R0, R0, # 1; Tăng R0
ADD R0, R0, R0, LSL # 2; Nhiều R0 5
ADDS R2, R2, R7; Thêm kết quả; kiểm tra tràn
ADD R0, R0, R0, LSL # 2; Nhiều R0 5
ADDS R2, R2, R7; Thêm kết quả; kiểm tra tràn
ADC Addition với carry
Các add với hoạt động carry là rất tương tự như ADD , với sự khác biệt mà cờ carry được thêm vào. Trong khi đó, chức năng của Thanh có thể được viết:
<ĐÍCH> = <LHS> + <RHS>
chúng ta phải thêm một phần thêm cho ADC :
<ĐÍCH> = <LHS> + <RHS> + <carry>
nơi <thực> là 0 nếu C là xóa và 1 nếu nó được thiết lập. Mục đích của ADC là cho phép đa từ ngoài diễn ra, như ví dụ minh họa.
Thí dụ:
; Thêm số 64-bit trong R2, R3 để rằng trong R0, R1
ADDS R0, R0, R2; Thêm những lời thấp, nhận carry
ADC R1, R1, R3; Thêm từ phía trên, sử dụng carrySUB Subtract
ADDS R0, R0, R2; Thêm những lời thấp, nhận carry
ADC R1, R1, R3; Thêm từ phía trên, sử dụng carrySUB Subtract
Hướng dẫn này sẽ trừ các <RHS> toán hạng từ <LHS> toán hạng, lưu trữ các kết quả trong <ĐÍCH> . Các phép trừ là một ba mươi hai bit đã ký hoạt động.
Ví dụ:
SUB R0, R0, # 1; Decrement R0
SUB R0, R0, R0, ASR # 2; Multiply R0 bằng 3/4 (R0 = R0-R0 / 4)
SUB R0, R0, R0, ASR # 2; Multiply R0 bằng 3/4 (R0 = R0-R0 / 4)
SBC Subtract với carry
Điều này có mối quan hệ tương tự để SUB như ADC phải ADD . Các hoạt động có thể được viết:
<ĐÍCH> = <LHS> - <RHS> - KHÔNG <carry>
Chú ý rằng các carry được đảo ngược bởi vì lá cờ C được xóa bởi một trừ mà cần một người mượn và thiết lập bởi một trong đó đã không. Chừng trừ nhiều từ được thực hiện bằng cách sử SUBS cho từ thấp nhất và SBCS cho những người tiếp theo, cách thức mà các carry được thiết lập không nên quan tâm lập trình viên.
Thí dụ:
; Trừ số 64-bit trong R2, R3 từ đó trong R0, R1
SUBS R0, R0, R2; Sub các từ thấp hơn, nhận được mượn
SBC R1, R1, R3; Sub lời trên, sử dụng vay
SUBS R0, R0, R2; Sub các từ thấp hơn, nhận được mượn
SBC R1, R1, R3; Sub lời trên, sử dụng vay
RSB trừ Xếp
hướng dẫn này thực hiện một trừ đi mà không mang theo, nhưng đảo ngược thứ tự các toán hạng của nó được khấu trừ. Các hướng dẫn:
RSB <đích>, <LHS>, <RHS>
thực hiện các hoạt động:
<ĐÍCH> = <RHS> - <LHS>
Các hướng dẫn được cung cấp để toàn bộ sức mạnh của <RHS> toán hạng (đăng ký, ngay lập tức, chuyển đăng ký) có thể được sử dụng trên cả hai phía của một phép trừ. Ví dụ, để có được kết quả 1-R1 trong thanh ghi R0, bạn sẽ phải sử dụng:
Mvn R0, R1; có được không (R1) = -R1-1
ADD R0, R0, # 2; nhận -R1-1 + 2 = 1-R1
ADD R0, R0, # 2; nhận -R1-1 + 2 = 1-R1
Tuy nhiên, sử dụng RSB này có thể được viết:
RSB R0, R1, # 1; R0 = 1 - R0
Trong ví dụ phức tạp hơn, đăng ký thêm có thể là cần thiết để giữ kết quả tạm thời, nếu trừ chỉ có thể hoạt động theo một hướng.
Thí dụ:
; Multiply R0 7
RSB R0, R0, R0, ASL # 3; Nhận 8 * R0-R0 = 7 * R0
RSB R0, R0, R0, ASL # 3; Nhận 8 * R0-R0 = 7 * R0
RSC Xếp trừ với carry
Đây là 'với carry' phiên bản của RSB . Hoạt động của nó là:
<ĐÍCH> = <RHS> - <LHS> - KHÔNG <carry>
Nó được sử dụng để thực hiện nhiều chữ trừ đảo ngược.
Thí dụ
; Lấy & 100000000-R0, R1 R0, R1
RSBS R0, R0, # 0; Sub các từ thấp hơn, nhận được mượn
RSC R1, R1, # 1; Sub các từ trên
RSBS R0, R0, # 0; Sub các từ thấp hơn, nhận được mượn
RSC R1, R1, # 1; Sub các từ trên
CMP So sánh
Các CMP hướng dẫn được sử dụng để so sánh hai số. Nó làm điều này bằng cách trừ đi một từ khác, và thiết lập các cờ trạng thái theo kết quả. Giống như TEQ và TST , CMP không thực sự lưu trữ kết quả ở bất cứ đâu. Định dạng của nó là:
CMP <LHS>, <RHS>
Cũng như TST và TEQ nó không yêu cầu S tùy chọn được thiết lập, như CMP mà không cần thiết lập các cờ sẽ không làm bất cứ điều gì cả.
Sau một CMP , các điều kiện khác nhau có thể được sử dụng để thực hiện hướng dẫn theo các mối quan hệ giữa các số nguyên. Lưu ý rằng hai toán hạng là so có thể được coi là một trong hai ký (bổ sung hai nhân) hoặc số lượng không dấu, tùy thuộc vào các điều kiện được sử dụng.
Xem phần "Sử dụng R15 trong một nhóm hướng dẫn 'dưới đây.
Ví dụ:
CMP R0, # & 100; Kiểm tra R0 mất một byte đơn
CMP R0, R1; Get lớn hơn R1, R0 R0 trong
MOVLT R0, R1
CMP R0, R1; Get lớn hơn R1, R0 R0 trong
MOVLT R0, R1
CMN So sánh tiêu cực
Các CMN hướng dẫn so sánh hai con số, nhưng phủ nhận phía bên tay phải trước khi thực hiện việc so sánh. Do đó, 'trừ' thực hiện là <LHS> - <RHS> , hoặc chỉ đơn giản là <LHS> + <RHS> . Tác dụng chính củaCMN là so sánh một đăng ký với một số ngay lập tức tiêu cực nhỏ, mà sẽ không nếu không có thể mà không cần nạp số vào sổ đăng ký (sử dụng mvn ). Ví dụ, so sánh với -1 sẽ yêu cầu
Mvn R1, # 0; -1 Nhận trong R1
CMP R0, R1; Do sự so sánh
CMP R0, R1; Do sự so sánh
trong đó sử dụng hai hướng dẫn và một thanh ghi phụ, so với điều này:
CMN R0, # 1; So sánh R0 với -1
Lưu ý rằng trong khi mvn là "di chuyển không ', CMN là" so sánh tiêu cực ', vì vậy có một sự khác biệt nhỏ trong cách <RHS> bị thay đổi trước khi được sử dụng trong các hoạt động.
Xem phần "Sử dụng R15 trong một nhóm hướng dẫn 'dưới đây.
Thí dụ
CMN R0, # 256; Hãy chắc chắn rằng R0> = -256
MVNLT R0, # 255
MVNLT R0, # 255
Sử dụng R15 trong một nhóm hướng dẫn
Như chúng ta biết, R15 là một thanh ghi mục đích chung, và như vậy có thể được trích dẫn trong các trường hợp đăng ký một là cần thiết như một toán hạng. Tuy nhiên, nó cũng được sử dụng để lưu trữ cả hai chương trình truy cập và đăng ký hộ. Bởi vì điều này, có một số quy tắc đặc biệt mà phải được tuân theo khi bạn sử dụng R15. Chúng được mô tả trong phần này.
Nguyên tắc đầu tiên liên quan đến bao nhiêu của R15 là 'nhìn thấy' khi nó được sử dụng như là một trong các toán hạng nguồn, tức là trong một <RHS> hoặc <LHS> vị trí. Đơn giản mà nói, đó là:
- nếu <LHS> là R15 thì chỉ bit 2..25 (máy tính) có thể nhìn thấy
- nếu <RHS> là R15 sau đó tất cả các bit 0..31 có thể nhìn thấy
Vì vậy, trong hướng dẫn:
ADD R0, R15, # 128
kết quả của việc thêm 128 máy vi tính được lưu trữ trong R0. Tám bit trạng thái của R15 được xem như là số không bởi ALU, và vì vậy họ không tìm trong việc bổ sung. Cũng nên nhớ rằng giá trị của máy tính được trình bày cho các ALU trong việc bổ sung là tám lớn hơn địa chỉ của Thanh chính nó, vì pipelining (điều này được mô tả chi tiết dưới đây).
Trong hướng dẫn
MOV R0, R15, ROR # 26
tất cả 32 bit của R15 được sử dụng, như thời gian này đăng ký đang được sử dụng trong một <RHS> vị trí. Ảnh hưởng của hướng dẫn này là để có được tám bit trạng thái trong byte thấp của R0.
Các mối quan tâm thứ hai quy tắc sử dụng R15 như toán hạng đích. Trong các mô tả hướng dẫn ở trên, chúng tôi cho rằng (nếu S là hiện tại) các bit trạng thái N, Z, C và C được xác định bởi kết quả của lệnh.Ví dụ, một kết quả của không sẽ gây ra các bit Z được thiết lập.
Trong các trường hợp khi R15 chính là ghi đích, hành vi này thay đổi. Nếu S không được đưa ra trong hướng dẫn, chỉ các bit PC của R15 bị ảnh hưởng, như thường lệ. Vì vậy, các hướng dẫn
ADD R15, R15, R0
cho biết thêm một số dịch chuyển này được lưu trong R0 để chương trình truy cập, để lại tình trạng không bị ảnh hưởng.
Nếu S có mặt trong giảng dạy và hướng dẫn không phải là một trong những TST , TEQ , CMP , hoặc CMN (được giải thích dưới đây), các bit trạng thái được phép được thay đổi trong chế độ xử lý hiện hành được ghi đè trực tiếp bởi kết quả. (Trái ngược với tình trạng của các kết quả.) Một ví dụ nên rõ ràng này. Để thiết lập một cách rõ ràng cờ carry (bit 29 của R15), chúng tôi có thể sử dụng:
ORRS R15, R15, # & 20000000
Bây giờ, khi R15 thứ hai là trong một <LHS> vị trí, các bit trạng thái được trình bày như là số không tới ALU (vì các quy tắc đầu tiên được mô tả ở trên). Như vậy giá trị ghi vào Sổ đăng ký hộ là (trong hệ nhị phân) 001.000 ... 00. Trong thực tế, trong các chế độ sử dụng, chỉ có bốn bit đầu có thể bị ảnh hưởng (tức là các mặt nạ ngắt và bit chế độ xử lý không thể được thay đổi trong chế độ người dùng).
Ví dụ trên có (thường) tác dụng không mong bỏ qua hai hướng dẫn mà làm theo Orr . Đây là, như thường lệ, do pipelining. Giá trị R15 mà được chuyển vào ALU giữ địa chỉ của lệnh thứ ba sau khi dòng điện một, do đó các can thiệp hai không bao giờ được thực thi. (Họ đã tìm nạp trước vào đường ống, nhưng bất cứ khi nào máy tính bị thay đổi, ARM đã bỏ qua các hướng dẫn trước khi lấy hiện tại.)
Để khắc phục điều này có một cách đặc biệt bằng văn bản cho các bit trạng thái, và chỉ có các bit trạng thái, của R15. Nó bao gồm việc sử dụng bốn hướng dẫn mà thường không có một ghi đích: TST , TEQ ,,CMP , và CMN . Như chúng ta biết, các thường ảnh hưởng đến những lá cờ từ kết quả của hoạt động này bởi vì họ có một tiềm ẩn S tùy chọn built-in. Ngoài ra, thường là lắp ráp làm cho <ĐÍCH> một phần của mã lệnh R0 (nó vẫn có lĩnh vực này trong hướng dẫn, ngay cả khi nó không được đưa ra trong các ngôn ngữ lắp ráp).
Bây giờ, nếu <ĐÍCH> lĩnh vực của một trong những hướng dẫn này được thực hiện R15 thay vào đó, là một điều hữu ích sẽ xảy ra. Các bit trạng thái được cập nhật từ các kết quả của các hoạt động (các VÀ ,EOR , SUB hoặc ADD thích hợp), nhưng phần máy tính vẫn không thay đổi.
Vấn đề là làm thế nào để làm cho R15 sử dụng lắp ráp trong <ĐÍCH> lĩnh vực thay vì R0. Điều này được thực hiện bằng cách thêm một P để hướng dẫn. Để đưa ra một ví dụ cụ thể, chúng tôi sẽ hiển thị như thế nào cờ carry có thể được thiết lập mà không cần bỏ qua hai hướng dẫn tiếp theo:
TEQP R15, # & 20000000
Điều này hoạt động như sau. Các R15 là một <LHS> vì vậy các bit trạng thái xuất hiện như là số không tới ALU. Như vậy EOR ing mặt nạ cho lá cờ carry với kết quả này trong bit được thiết lập khi kết quả được chuyển giao cho R15. Phần còn lại của thanh ghi trạng thái (hoặc ít nhất là các bit đó là alterable) sẽ bị xóa.
Thiết lập và thanh toán bù trừ bit trạng thái chỉ được lựa chọn trong khi rời khỏi phần còn lại một mình sẽ nỗ lực nhiều hơn một chút. Đầu tiên là giá trị hiện tại của các bit phải được lấy. Sau đó, mặt nạ thích hợp được thực hiện và kết quả được lưu trữ trong R15. Ví dụ, để xóa cờ tràn (bit 28) trong khi vẫn giữ phần còn lại, một cái gì đó như thế này là cần thiết:
MOV tmp, R15; Lấy tình trạng
BIC tmp, tmp, # 1 << 28: xóa cắn 28
TEQP R15, tmp; Store trạng thái mới
BIC tmp, tmp, # 1 << 28: xóa cắn 28
TEQP R15, tmp; Store trạng thái mới
Cuối cùng, chúng tôi phải nói điều gì đó về biểu diễn số học trên R15 để thay đổi con đường thực hiện của chương trình. Như chúng ta sẽ thấy sau này trong chương này, có một đặc biệt B (đối với Chi nhánh) hướng dẫn, làm cho máy tính để đưa vào một giá trị mới, Điều này gây ra một bước nhảy đến một phần của chương trình, tương tự như BASIC GOTO tuyên bố. Tuy nhiên, bằng cách thay đổi giá trị của R15 sử dụng nhóm một hướng dẫn như Thanh , chúng ta có thể đạt được điều khiển linh hoạt hơn, ví dụ thi đua các BASIC ON..GOTO tuyên bố.
Điều quan trọng cần nhớ khi làm việc với máy tính đã được đề cập một lần hoặc hai lần: ảnh hưởng của pipelining. Giá trị thu được khi R15 được sử dụng như một toán hạng là 8 byte, hoặc 2 chữ, lớn hơn các địa chỉ của lệnh hiện hành. Vì vậy, nếu các chỉ dẫn
MOV R0, R15
được đặt tại địa chỉ & 8000, sau đó các giá trị nạp vào R15 sẽ là & 8008. Chương Năm và Sáu chứa một số ví dụ về việc sử dụng R15 nơi pipelining được đưa vào tài khoản.
Nhóm One A
Có một lớp học nhỏ của hướng dẫn mà là dạng tương tự như nhóm một hướng dẫn, nhưng không thuộc trong nhóm đó. Đây là những hướng dẫn nhân, người mà mang một sự tương đồng với hình thức đơn giản nhất của nhóm một hướng dẫn.
Hai hoạt động riêng biệt tạo nên nhóm này, nhân và nhân với tích lũy. Các định dạng là:
MUL {cond} {S} <dest, <LHS>, <RHS>
MLA {cond} {S} <đích>, <LHS>, <RHS>, <add>
MLA {cond} {S} <đích>, <LHS>, <RHS>, <add>
Tất cả các toán hạng là đăng ký đơn giản; không có toán hạng ngay lập tức hoặc chuyển đăng ký. MUL nhân lên <LHS> bởi <RHS> và lưu trữ kết quả trong <ĐÍCH> . MLA không giống nhau, nhưng bổ sung thêm register <add> trước khi lưu trữ kết quả.
Bạn phải tuân thủ những hạn chế nhất định trên các toán hạng khi sử dụng những hướng dẫn này. Việc đăng ký sử dụng cho <RHS> và <ĐÍCH> phải khác. Ngoài ra, bạn không nên sử dụng R15 như một điểm đến, vì điều này sẽ tạo ra một kết quả vô nghĩa. Trong thực tế, R15 được bảo vệ từ sửa đổi bởi các hướng dẫn nhân. Không có hạn chế khác.
Nếu S tùy chọn được chỉ định, những lá cờ được ảnh hưởng như sau. N và Z cờ được thiết lập để phản ánh tình trạng của thanh ghi kết quả, giống như phần còn lại của nhóm một hướng dẫn. Cờ tràn là không thay đổi, và cờ carry là không xác định.
Bạn có thể xem các toán hạng của các hướng dẫn nhân như unsigned hoặc hai của bổ sung chữ ký số. Trong cả hai trường hợp, kết quả chính xác sẽ được lấy.
Thí dụ:
MUL R0, R1, R2
Tóm tắt của một nhóm
Các nhóm một hướng dẫn có các hình thức sau đây:
<op1> {cond} {S} {P} <đích>, <LHS>, <RHS>
<op2> {cond} {S} {P} <đích>, <RHS>
<op3> {cond} {S } {P} <LHS>, <RHS>
<op2> {cond} {S} {P} <đích>, <RHS>
<op3> {cond} {S } {P} <LHS>, <RHS>
nơi <op1 > là một trong Thanh , ADC , VÀ , BIC , EOR , Orr , RSB , RSC , SBC , SUB , <op2> là một trong MOV , mvn , và <op3> là một trong TEQ , TST , CMN , CMP .
Sau đây <op3> s không có <ĐÍCH> lĩnh vực: CMN , CMP , TEQ , TST . Chúng cho phép người sử dụng {P} tùy chọn để thiết lập <ĐÍCH> trường trong mã máy để R15 thay vì R0 mặc định.
Sau đây <op2> s không có <LHS> lĩnh vực: MOV , mvn .
- <ĐÍCH> và <LHS> là các thanh ghi.
- <RHS> là # <expression> nơi <expression> là một 12-bit chuyển toán hạng ngay lập tức, hoặc
- <đăng ký> , hoặc
- <đăng ký>, <ca Loại> <count> nơi <ca Loại> là LSL , ASL , ASR , LSR , ROR và nơi <count> là # <expression> hoặc <đăng ký> nơi <expression> là năm-bit giá trị unsigned , hoặc là
- <Đăng ký>, RRX
3.3 Nhóm hai - tải và lưu trữ
Chúng tôi quay về các hướng dẫn đầu tiên liên quan đến việc nhận dữ liệu vào và ra khỏi bộ vi xử lý. Chỉ có hai hướng dẫn cơ bản trong thể loại này. LDR tải một đăng ký từ một vị trí xác định và STR tiết kiệm một thanh ghi.
Như với nhóm một, có một số tùy chọn mà làm cho các hướng dẫn rất linh hoạt. Là sự khác biệt chính giữa LDR và STR là hướng mà trong đó dữ liệu được chuyển (tức là đến hoặc từ bộ vi xử lý), chúng tôi sẽ chỉ giải thích một trong những hướng dẫn chi tiết - STR . Ghi chú về LDR theo mô tả này.
STR Lưu trữ một từ hoặc byte
Giải quyết chế độ
Khi lưu trữ dữ liệu vào bộ nhớ, bạn có để có thể xác định vị trí mong muốn. Có hai cách chính để đưa ra địa chỉ, gọi là giải quyết chế độ. Chúng được gọi là pre-lập chỉ mục và sau được lập chỉ mục địa chỉ.
Pre-lập chỉ mục địa chỉ
Pre-lập chỉ mục addressing được quy định như sau:
STR {cond} <srce>, [<base> {, <bù đắp>}]
<srce> là đăng ký từ đó dữ liệu sẽ được chuyển giao cho bộ nhớ. <base> là một thanh ghi chứa địa chỉ cơ sở của bộ nhớ vị trí cần thiết. <bù đắp> là một số tùy chọn được thêm vào địa chỉ trước khi các dữ liệu được lưu trữ . Vì vậy, địa chỉ thực tế sử dụng để lưu trữ các <srce> dữ liệu là <base> + <bù đắp>
bù đắp các định dạng
Các <bù đắp> được quy định tại một trong hai cách. Nó có thể là một số ngay lập tức trong khoảng 0-4095, hoặc một (có thể) chuyển đăng ký. Ví dụ:
STR R0, [R1, # 20]
sẽ lưu trữ R0 tại địa chỉ byte R1 + 20. Việc bù đắp có thể được quy định như tiêu cực, trong trường hợp đó nó được trừ từ địa chỉ cơ sở. Một ví dụ là:
STR R0, [R1, # - 200]
mà các cửa hàng R0 tại R1-200.
(Lưu ý cho người đọc báo. Các trực bù đắp được lưu giữ như một cường độ 12-bit cộng với một "phương hướng" chút, không phải là số bù 13-bit hai của. Vì vậy phạm vi bù đắp thực sự là -4.095-4095, không để -4096 4095, như bạn có thể mong đợi.)
Nếu bù đắp được quy định như đăng ký một, nó có cú pháp tương tự như <RHS> của nhóm một hướng dẫn. Đó là, nó có thể là một nội dung đăng ký đơn giản, hoặc các nội dung của một thanh ghi dịch chuyển hoặc xoay bởi một số ngay lập tức.
Lưu ý: đăng ký bù đắp chỉ có thể có một sự thay đổi ngay lập tức áp dụng cho nó. Trong khía cạnh này, bù đắp khác với các <RHS> của nhóm một hướng dẫn. Sau này cũng có thể có một sự thay đổi đó được lưu trữ trong một thanh ghi.
Ví dụ này lưu R0 vào địa chỉ do R1 + R2 * 4:
STR R0, [R1, R2, LSL # 2]
Một lần nữa, sự bù đắp có thể được tiêu cực như ví dụ này minh họa:
STR R0, [R1, -R2, LSL # 3]
Viết lại
Khá thường xuyên, một khi địa chỉ đã được tính toán, nó là thuận tiện để cập nhật thanh ghi cơ sở từ nó. Điều này cho phép nó được sử dụng trong hướng dẫn tiếp theo. Điều này rất hữu ích khi bước qua bộ nhớ tại một cố định bù đắp. Bằng cách thêm một ! Đến cuối của các hướng dẫn, bạn có thể buộc đăng ký cơ sở để được cập nhật từ <base> + <bù đắp> tính toán. Một ví dụ là:
STR R0, [R1, # - 16]!
Điều này sẽ lưu R0 tại địa chỉ R1-16, và sau đó thực hiện tự động:
SUB R1, R1, # 16
mà vì cách thức mà các ARM hoạt động, không đòi hỏi thêm bất cứ lúc nào.
hoạt động Byte và từ
Tất cả các ví dụ về STR , chúng tôi đã thấy cho đến nay đã giả định rằng địa chỉ cuối cùng là trên một ranh giới từ, tức là một bội số của 4. Đây là một hạn chế mà bạn phải tuân thủ khi sử dụng STR hướng dẫn.Tuy nhiên, nó có thể lưu trữ byte duy nhất mà có thể được đặt ở bất kỳ địa chỉ. Các hình thức byte của STR thu được bằng cách thêm B ở cuối. Ví dụ:
STRB R0, [R1, # 1]!
sẽ lưu trữ các byte thấp của R0 tại địa chỉ R1 + 1 và lưu trữ địa chỉ này trong R1 (như ! được sử dụng).
Post-lập chỉ mục địa chỉ
Các mode địa chỉ thứ hai mà STR và LDR sử dụng được gọi là hậu lập chỉ mục địa chỉ. Trong chế độ này, <bù đắp> không được thêm vào <base> cho đến khi sau khi chỉ lệnh đã thực hiện. Định dạng chung của một bài lập chỉ mục STR là:
STR {cond} <srce>, [<base>] <bù đắp>
Các <base> và <bù đắp> toán hạng có định dạng giống như trước được lập chỉ mục địa chỉ. Lưu ý rằng mặc dù <bù đắp> luôn luôn hiện diện, và viết lại luôn xảy ra (vì vậy không ! Là cần thiết). Như vậy các chỉ dẫn:
STRB R0, [R1], R2
sẽ tiết kiệm byte thấp của R0 tại địa chỉ R1. Sau đó R1 được thiết lập để R1 + R2. Các <bù đắp> chỉ được sử dụng để cập nhật các <base> đăng ký ở cuối hướng dẫn. Một ví dụ với một ngay lập tức <bù đắp>là:
STR R2, [R4], # - 16
mà các cửa hàng R2 tại địa chỉ tổ chức tại R4, sau đó decrements R4 bằng 4 từ.
LDR Load một từ hoặc byte
Các LDR hướng dẫn tương tự như ở hầu hết các khía cạnh để STR . Sự khác biệt chính là, tất nhiên, đó là toán hạng đăng ký được tải từ địa chỉ nhất định, thay vì lưu nó.
Các chế độ địa chỉ giống hệt nhau, và B tùy chọn để tải một byte duy nhất (đệm bằng số không) vào byte thấp của thanh ghi được cung cấp.
Khi một nỗ lực được thực hiện để LDR một lời từ một ranh giới không từ, hành động khắc phục đặc biệt được thực hiện. Nếu địa chỉ tải là addr , sau đó từ tại addr VÀ & 3FFFFFFC được tải. Đó là, hai bit quan trọng nhất của địa chỉ được thiết lập để không, và các nội dung của địa chỉ Word được truy cập. Sau đó, các thanh ghi được xoay đúng bằng (addr MOD 4) * 8 bit. Để xem tại sao điều này được thực hiện, xem xét ví dụ sau đây. Giả sử nội dung của địa chỉ & 1000 & 76.543.210. Bảng dưới đây cho thấy các nội dung của R0 sau khi tải từ từ các địa chỉ khác nhau:
Địa chỉ nhà
|
R0
|
& 1000 | & 76543210 |
& 1001 | & 10765432 |
& 1002 | & 32107654 |
& 1003 | & 54321076 |
Lưu ý rằng LDR và STR sẽ không bao giờ ảnh hưởng đến các bit trạng thái, thậm chí nếu <ĐÍCH> hoặc <base> là R15. Ngoài ra, nếu R15 được sử dụng như đăng ký cơ sở, pipelining nghĩa là giá trị sử dụng sẽ cao hơn so với các địa chỉ của lệnh tám byte. Điều này được đưa vào tài khoản tự động khi máy tính tương đối quyết được sử dụng.
PC tương đối quyết
Việc lắp ráp sẽ chấp nhận một hình thức đặc biệt của địa chỉ trước được lập chỉ mục trong LDR hướng dẫn, mà chỉ đơn giản là:
LDR <đích>, <expression>
nơi <expression> mang lại một địa chỉ. Trong trường hợp này, các hướng dẫn được tạo ra sẽ sử dụng R15 (tức là chương trình truy cập) như đăng ký cơ sở, và tính toán ngay lập tức bù đắp tự động. Nếu địa chỉ cụ thể không thuộc phạm vi chính xác (-4.095-4095) từ lệnh, một lỗi được đưa ra.
Một ví dụ về hình thức giảng dạy là:
LDR R0, mặc định
(Chúng tôi giả định rằng mặc định là một nhãn trong chương trình. Nhãn được mô tả đầy đủ hơn trong chương tiếp theo, nhưng bây giờ đủ để nói rằng chúng được thiết lập đến địa chỉ của các điểm trong chương trình mà họ được xác định.)
Khi lắp ráp đều biết giá trị của máy tính khi chương trình được thực hiện, nó có thể tính toán ngay lập tức bù đắp cần thiết để truy cập vào các vị trí mặc định . Điều này phải nằm trong phạm vi -4.095-4095 tất nhiên. Đây là hình thức giải quyết được sử dụng thường xuyên để truy cập hằng nhúng trong chương trình.
Tóm tắt các LDR và STR
Dưới đây là một bản tóm tắt các cú pháp cho các phụ tải đăng ký và lưu hướng dẫn.
<op> {cond} {B} <đích>, [<base> {, # <imm>}] {!}
<op> {cond} {B} <đích>, [<base>, {+ | - } <off> {, <shift>}] {!}
<op> {cond} {B} <đích>, <expression>
<op> {cond} {B} <đích>, [<base>], # <imm>
<op> {cond} {B} <đích>, [<base>], {+ | -} <off> {, <shift>}
<op> {cond} {B} <đích>, [<base>, {+ | - } <off> {, <shift>}] {!}
<op> {cond} {B} <đích>, <expression>
<op> {cond} {B} <đích>, [<base>], # <imm>
<op> {cond} {B} <đích>, [<base>], {+ | -} <off> {, <shift>}
Mặc dù chúng tôi đã không được sử dụng bất kỳ ví dụ rõ ràng, nó là tiềm ẩn cho sự đều đặn của lệnh ARM thiết rằng bất kỳ LDR hoặc STR lệnh có thể được thực hiện có điều kiện bằng cách thêm mã hai chữ cái. Bất kỳ B tùy chọn sau này.
<op> nghĩa LDR hoặc STR . <imm> có nghĩa là một giá trị tức thời giữa -4095 và 4095. {+ | -} có nghĩa là một tùy chọn + hoặc - dấu hiệu có thể có mặt. <off> là số đăng ký bù đắp. <base> là một đăng ký cơ sở, và <chuyển> đề cập đến các tiêu chuẩn trước mắt (nhưng không đăng ký thay đổi) được mô tả trong phần trên vào nhóm một hướng dẫn.
Lưu ý rằng các trường hợp:
STR R0, nhãn
được bảo hiểm. Mặc dù lắp ráp sẽ chấp nhận điều này và tạo ra các hướng dẫn PC-tương đối phù hợp, sử dụng của nó ngụ ý rằng các chương trình được viết trên hoặc gần mã của nó. Nói chung đây là không nên bởi vì (a) nó có thể dẫn vô tình để quá viết chương trình với những hậu quả thảm khốc, và (b) nếu chương trình là để được đặt trong ROM, nó sẽ ngừng hoạt động, như ROM thường chỉ đọc thiết bị, trên toàn bộ.
3.4 Nhóm ba - nhiều tải và lưu trữ
Các nhóm hướng dẫn trước đó là rất thích hợp cho việc chuyển mục dữ liệu duy nhất vào và ra khỏi bộ vi xử lý ARM. Tuy nhiên, trường hợp này thường phát sinh nơi một số đăng ký cần phải được lưu (hoặc tải) cùng một lúc. Ví dụ, một chương trình có thể cần phải lưu nội dung của R1 đến R12 trong khi các thanh ghi được sử dụng cho một số tính toán, sau đó tải chúng trở lại khi kết quả đã thu được. Trình tự:
STR R1, [R0], # 4
STR R2, [R0], # 4
STR R3, [R0], # 4
STR R4, [R0], # 4
STR R5, [R0], # 4
STR R6, [R0 ], # 4
STR R7, [R0], # 4
STR R8, [R0], # 4
STR R9, [R0], # 4
STR R10, [R0], # 4
STR R11, [R0], # 4
STR R12, [R0], # 4
STR R2, [R0], # 4
STR R3, [R0], # 4
STR R4, [R0], # 4
STR R5, [R0], # 4
STR R6, [R0 ], # 4
STR R7, [R0], # 4
STR R8, [R0], # 4
STR R9, [R0], # 4
STR R10, [R0], # 4
STR R11, [R0], # 4
STR R12, [R0], # 4
để cứu họ là không hiệu quả cả về không gian và thời gian. Các LDM (load nhiều) và STM hướng dẫn (cửa hàng nhiều) được thiết kế để thực hiện các nhiệm vụ như một ở trên một cách hiệu quả.
Như với LDR và STR chúng tôi sẽ mô tả một biến thể chi tiết, tiếp theo ghi chú về sự khác biệt trong khác. Đầu tiên, mặc dù một lời về ngăn xếp.
về ngăn xếp
LDM và STM thường được sử dụng để lưu trữ các ghi trên, và lấy chúng từ, một chồng. Một stack là một khu vực của bộ nhớ mà 'mọc' theo một hướng như các mặt hàng được thêm vào nó, và 'co' khi chúng được đưa ra. Các mặt hàng đều được tháo bỏ khỏi ngăn xếp theo thứ tự ngược lại mà họ được thêm vào.
Thuật ngữ 'chồng' đến từ một tương tự với những chồng đĩa mà bạn nhìn thấy trong các nhà hàng tự phục vụ. Tấm được thêm vào đầu, sau đó lấy ra theo thứ tự ngược lại. Một tên cho một chồng là một cấu trúc đầu ra cuối cùng trong hoặc 'LIFO.
ngăn xếp tính toán có giá trị liên quan đến họ gọi là con trỏ ngăn xếp, hoặc SP. Các SP giữ địa chỉ của các mục tiếp theo sẽ được thêm vào (đẩy lên) hoặc gỡ bỏ (kéo) từ ngăn xếp. Trong một chương trình ARM, SP sẽ hầu như luôn được lưu trữ trong một trong các thanh ghi mục đích chung. Thông thường, một đăng ký cao số, ví dụ như R12 hoặc R13 được sử dụng. Tiêu chuẩn Acorn ARM gọi, ví dụ, quy định cụ thể R12, trong khi sử dụng BASIC R13.
Dưới đây là một đại diện bằng hình ảnh của hai mặt hàng bị đẩy lên một chồng.
Trước khi các mặt hàng được đẩy, điểm SP để (giữ địa chỉ của) các mục trước đó đã được đẩy. Sau hai từ mới đã bị đẩy, những điểm con trỏ ngăn xếp vào thứ hai trong số này, và từ đầu tiên đẩy dối 'bên dưới' nó.
Ngăn xếp trên ARM có hai thuộc tính đó phải được quyết định trước khi bất kỳ STM / LDM hướng dẫn được sử dụng. Các thuộc tính phải được sử dụng một cách nhất quán trong bất kỳ hoạt động hơn nữa trên stack.
Các thuộc tính đầu tiên là liệu ngăn xếp là 'đầy đủ' hoặc 'rỗng'. Một stack đầy đủ là một trong đó các điểm SP vào mục cuối cùng đẩy (như ví dụ trên). Một ngăn xếp rỗng là nơi con trỏ ngăn xếp giữ địa chỉ của các khe rỗng nơi tới mục sẽ được đẩy.
Thứ hai, một chồng được cho là tăng dần hoặc giảm dần. Một tăng dần ngăn xếp là một trong những nơi SP được tăng lên khi các mặt hàng được đẩy và giảm đi khi các mặt hàng được kéo. Một ngăn xếp giảm dần lớn lên và nhỏ theo hướng ngược lại. Với sự chỉ đạo của tăng trưởng trong ví dụ trên, các ngăn xếp có thể được nhìn thấy được giảm dần.
Acorn nói trên kêu gọi chuẩn (trong đó xác định cách thức mà các chương trình riêng biệt có thể giao tiếp) xác định đầy đủ, giảm dần stack, và BASIC cũng sử dụng một.
STM trữ nhiều đăng ký
Trong bối cảnh những gì vừa được nói, STM là 'mục đẩy vào stack' hướng dẫn. Mặc dù nó có công dụng khác, nhất STM s được ngăn xếp theo định hướng.
Dạng tổng quát của các hướng dẫn STM là:
STM <type> <base> {!} <Đăng ký>
Chúng tôi đã bỏ qua {} cond cho rõ ràng, nhưng như thường lệ một mã điều kiện có thể được đưa vào ngay sau khi ghi nhớ. Các <type> bao gồm hai chữ cái mà xác định F ull / E mpty, Một scending / D chế độ của ngăn xếp escending. Bức thư đầu tiên là F hoặc E ; thứ hai là A hoặc D .
Các <base> đăng ký là con trỏ ngăn xếp. Như với LDR / STR , các ! Tùy chọn sẽ gây ra ghi lại nếu có. <Đăng ký> là một danh sách của các thanh ghi mà chúng tôi muốn đẩy. Nó được xác định là một danh sách các số đăng ký phân cách bằng dấu phẩy, kèm theo trong dấu ngoặc (ngoặc nhọn). Bạn cũng có thể chỉ định một danh sách đăng ký sử dụng một - dấu hiệu, ví dụ như R0-R4 là viết tắt cho R0, R1, R2, R3, R4.
Ví dụ đầu tiên của chúng tôi về một STM hướng dẫn là:
STMED R13!, {R1, R2, R5}
Điều này sẽ tiết kiệm được ba thanh ghi R1, R2 và R5 sử dụng R13 như SP. Như ghi lại được chỉ định, R13 sẽ được cập nhật bằng cách trừ đi 3 * 4 (12) từ giá trị ban đầu của nó (trừ khi chúng ta đang sử dụng một ngăn xếp giảm dần). Bởi vì chúng tôi đã xác định các E tùy chọn, ngăn xếp rỗng, tức là sau khi STM , R13 sẽ giữ địa chỉ của từ tiếp theo được đẩy. Địa chỉ của từ cuối cùng đẩy là R13 + 4.
Khi sử dụng STM và LDM cho các hoạt động ngăn xếp, bạn sẽ hầu như luôn sử dụng ! Lựa chọn, như các con trỏ ngăn xếp đã được cập nhật. Trường hợp ngoại lệ là khi bạn muốn để có được một bản sao của một mục mà không cần kéo nó, và khi bạn cần để lưu trữ kết quả trong một 'khe' đã được tạo ra cho nó vào stack. Cả hai kỹ thuật được sử dụng trong 'tìm substring' dụ của Chương Sáu.
Thêm chi tiết về FD, vv
Các chế độ tăng / giảm dần của một chồng là tương tự với hiệu tích cực và tiêu cực của phần trước. Trong một STM , nếu stack được giảm dần, một tiêu cực bù đắp của 4 được sử dụng. Nếu ngăn xếp là tăng dần, một tích cực bù đắp của 4 được sử dụng (đối với mỗi thanh ghi).
Tương tự như vậy, sự khác biệt giữa những gì ARM làm cho ngăn xếp đầy đủ và trống rỗng trong một STM là tương tự như trước và sau khi lập chỉ mục giải quyết chế độ của các phần trước. Hãy xem xét một ngăn xếp giảm dần. Con trỏ một ngăn xếp rỗng là hậu giảm đi khi một mục được đẩy. Đó là, các đăng ký để được đẩy được lưu trữ tại vị trí hiện tại, sau đó con trỏ ngăn xếp được giảm đi (do một cố định bù đắp của 4), sẵn sàng cho một kế tiếp. Một stack đầy đủ trước giảm đi trên một đẩy: SP đầu tiên được giảm đi 4, sau đó đăng ký được lưu trữ ở đó. Điều này được lặp lại cho mỗi đăng ký trong danh sách.
Hướng lưu trữ
Dưới đây là một STM mà các cửa hàng tất cả các đăng ký tại vị trí trỏ đến bởi R13, nhưng không ảnh hưởng đến R13 (không ghi lại).
STMFD R13, {R0-R15}
Mặc dù chồng là một FD một, bởi vì không có ghi lại, R13 là không thực sự giảm đi. Như vậy sau khi hoạt động, R13 điểm cho một số mục trước đó, và dưới đó trong bộ nhớ là mười sáu đẩy từ.
Bây giờ, khi R0 xuất hiện đầu tiên trong danh sách, bạn có thể mong đợi rằng để được đăng ký đầu tiên được đẩy, và phải được lưu trữ tại địa chỉ R13-4. Vâng, bạn sẽ là sai lầm. Thứ nhất, thứ tự trong danh sách đăng ký xuất hiện không có mang cả vào thứ tự mà mọi thứ được thực hiện. Tất cả các nhà lắp ráp đang tìm kiếm là một đề cập đến tên của một đăng ký: nó có thể xuất hiện bất cứ nơi nào trong các dấu ngoặc. Thứ hai, đăng ký luôn được lưu trữ trong cùng một thứ tự trong bộ nhớ, cho dù ngăn xếp là tăng dần hoặc giảm dần, đầy hoặc rỗng.
Khi bạn đẩy một hoặc nhiều đăng ký, các cửa hàng ARM thấp nhất đánh số một tại địa chỉ thấp nhất, cao nhất tiếp theo đánh số một tại địa chỉ tiếp theo và như vậy. Điều này luôn luôn xảy ra. Đối với tăng dần ngăn xếp, con trỏ vị trí được cập nhật, đăng ký đầu tiên được lưu trữ (hoặc ngược lại đối với ngăn xếp rỗng) và như vậy cho mỗi đăng ký. Cuối cùng, nếu ghi lại được kích hoạt, con trỏ ngăn xếp được cập nhật bởi các con trỏ vị trí.
Để giảm dần ngăn xếp, giá trị cuối cùng của con trỏ ngăn xếp được tính trước. Sau đó, các thanh ghi này được lưu trữ trong tăng bộ nhớ vị trí, và cuối cùng là con trỏ ngăn xếp được cập nhật nếu cần thiết.
Chúng tôi đi vào chi tiết này, vì nếu bạn cần phải truy cập đẩy đăng ký trực tiếp từ stack, điều quan trọng là phải biết họ đang ở đâu!
Tiết kiệm con trỏ ngăn xếp và PC
Trong ví dụ trước, con trỏ ngăn xếp (R13) là một trong những thanh ghi đẩy. Vì không có ghi lại, giá trị của R13 vẫn không đổi trong suốt các hoạt động, vì vậy không có vấn đề gì giá trị đã thực sự được lưu trữ. Tuy nhiên, trong trường hợp ghi lại được kích hoạt, các SP thay đổi giá trị tại một số thời gian trong quá trình hướng dẫn, do đó 'trước khi' hoặc 'sau khi' phiên bản có thể được cứu.
Các quy tắc để xác định xem phiên bản của thanh ghi cơ sở được lưu là khá đơn giản. Nếu con trỏ stack là thấp nhất số một trong danh sách, sau đó giá trị được lưu trữ là bản gốc, không thay đổi gì một. Nếu không, các giá trị được viết lại của thanh ghi cơ sở được mà được lưu trữ trên stack. Vì chúng tôi đã tiêu chuẩn hóa trên R13 cho con trỏ ngăn xếp, nó gần như luôn luôn là giá trị mới mà được lưu trữ.
Khi R15 được bao gồm trong danh sách đăng ký, tất cả 32-bit được lưu trữ, tức là cả hai máy tính và tình trạng phần đăng ký.
LDM tải nhiều đăng ký
LDM hiện chồng 'kéo' (hoặc pop như nó còn được gọi) hoạt động. Nó rất giống trong hình thức để các STM hướng dẫn:
LDM <type> <base> {!} <Đăng ký> {^}
Như trước đây, <type> cung cấp cho các hướng và kiểu của stack. Khi kéo đăng ký, bạn phải sử dụng cùng một loại ngăn xếp như khi họ bị đẩy, nếu không thì giá trị sai sẽ được nạp. <Base> , ! Và <đăng ký>là tất cả như STM .
Các chỉ thêm 'quay vòng' được cung cấp bởi LDM là ^ mà có thể xuất hiện ở cuối. Nếu có, điều này chỉ ra rằng nếu R15 là trong danh sách đăng ký, sau đó tất cả 32-bit sẽ được cập nhật từ các giá trị lấy từ các stack. Nếu không có ^ trong hướng dẫn, sau đó nếu R15 được kéo, chỉ có phần PC (bit 2-25) đều bị ảnh hưởng. Các bit trạng thái của R15 sẽ vẫn không thay đổi do hoạt động.
Điều này cho phép bạn quyết định liệu chương trình con (được giải thích chi tiết trong phần tiếp theo) bảo tồn các cờ trạng thái hoặc sử dụng chúng để trả lại kết quả. Nếu bạn muốn có thủ tục để bảo vệ lá cờ, sau đó sử dụng ^ để khôi phục lại chúng từ stack. Nếu không bỏ qua nó, và những lá cờ sẽ giữ lại nội dung trước đó của họ.
Đang tải con trỏ ngăn xếp và PC
Nếu đăng ký được sử dụng như là con trỏ ngăn xếp là trong LDM danh sách đăng ký, giá trị của thanh ghi sau khi dạy luôn luôn là kẻ bị nạp, không phân biệt nơi nó xuất hiện trong danh sách, và liệu ghi lại đã được chỉ định.
Nếu R15 xuất hiện trong danh sách, sau đó ^ tùy chọn được sử dụng để xác định xem máy tính của mình hoặc máy tính cộng với tình trạng đăng ký được tải. Điều này được mô tả ở trên.
Một ký hiệu thay thế
Không phải tất cả những ứng dụng cho LDM và STM liên quan đến ngăn xếp. Trong những tình huống này, các / trống, tăng / giảm điểm đầy đủ của các hoạt động có thể không phải là phù hợp nhất. Việc lắp ráp công nhận một bộ thay thế các chữ cái tùy chọn, mà trong thực tế phản ánh gần hơn những gì các hướng dẫn ARM thực sự làm.
Các cặp thư thay thế là tôi / D cho tăng / giảm, và B / A cho trước / sau. Như vậy các chỉ dẫn:
STMIA R0!, {R1, R2}
cửa hàng R1 và R2 theo địa chỉ trong R0. Đối với mỗi cửa hàng, một bài thặng dư ( Tôi ncrement Một fter) được thực hiện, và các giá trị mới (R0 + 8) được viết lại. tương tự như vậy:
LDMDA R0!, {R1, R3, R4}
tải ba thanh ghi chỉ định, giảm các địa chỉ sau mỗi một. Các tùy chọn ghi lại nghĩa là R0 sẽ được giảm đi 12. Hãy nhớ rằng đăng ký luôn được lưu trữ thấp nhất tại địa chỉ thấp, vì vậy trong điều khoản của R0 gốc, sổ đăng ký trong danh sách sẽ được tải từ địa chỉ R0-8, R0-4 và R0-0 tương ứng.
Bảng dưới đây cho thấy các khoản tương đương cho hai loại ký hiệu:
Toàn trống rỗng
|
Sụt lần / Tăng
tương đương |
STMFD | STMDB |
LDMFD | LDMIA |
STMFA | STMIB |
LDMFA | LDMDA |
STMED | STMDA |
LDMED | LDMIB |
STMEA | STMIA |
LDMEA | LDMDB |
Tóm tắt các LDM / STM
LDM {cond} <type1> <base> {!} <Đăng ký> {^}
LDM {cond} <type2> <base> {!} <Đăng ký> {^}
STM {cond} <type1> <base> {!} <đăng ký> {} ^
STM {cond} <type2> <base> {!} <đăng ký> {^}
LDM {cond} <type2> <base> {!} <Đăng ký> {^}
STM {cond} <type1> <base> {!} <đăng ký> {} ^
STM {cond} <type2> <base> {!} <đăng ký> {^}
Ở đâu:
cond được định nghĩa ở đầu chương này.
<type1> là F | E A | D <type2> là tôi | D B | A <base> là một đăng ký
<đăng ký> là mở ngoặc bằng dấu phẩy-danh sách gần-cú đúp
Chú ý rằng ^ có thể được sử dụng trong STM cũng như LDM . Việc sử dụng nó trong STM là chỉ liên quan đến chế độ không sử dụng, và như vậy được mô tả trong Chương Bảy.
3.5 Nhóm bốn - chi nhánh
Về lý thuyết, các nhóm một hướng dẫn dữ liệu có thể được sử dụng để thực hiện bất kỳ thay đổi để các máy tính theo yêu cầu của một chương trình. Ví dụ, một Thanh để R15 có thể được sử dụng để di chuyển các máy tính trên bằng một số tiền, gây ra một bước nhảy về phía trước trong chương trình. Tuy nhiên, có những giới hạn cho những gì bạn có thể đạt được thuận tiện sử dụng những hướng dẫn này có mục đích chung. Các nhóm ngành cung cấp khả năng xác định vị trí bất kỳ điểm nào trong chương trình với một thao tác đơn giản.
Các chi nhánh đơn giản
Nhóm bốn chỉ gồm hai biến thể của lệnh rẽ nhánh. Có (mới mẻ có lẽ) không có thay thế định dạng toán hạng hoặc tính năng bổ sung tùy chọn. Các hướng dẫn cơ bản là một ngành đơn giản, dễ nhớ mà chỉ làB . Các định dạng của lệnh là:
B {cond} <expression>
Điều kiện bắt buộc, khi có mặt, làm cho dễ nhớ một bình thường tìm kiếm nhiều hơn ba chữ một, ví dụ như BNE , BCC . Nếu bạn thích ba chữ cái, bạn luôn có thể thể hiện các chi nhánh không điều kiện nhưBAL , mặc dù các nhà lắp ráp sẽ được hài lòng với chỉ B .
<expression> là địa chỉ trong phạm vi chương trình mà bạn muốn chuyển giao kiểm soát. Thông thường, nó chỉ là một nhãn hiệu được định nghĩa ở nơi khác trong chương trình. Ví dụ, một vòng lặp đếm đơn giản sẽ được thực hiện như sau:
MOV R0, # 0; Init đếm bằng không
.LOOP MOVS R1, R1, LSR # 1; Hãy đến cạnh 1 chút trong Carry
ADC R0, # 0; Thêm nó đếm
BNE LOOP; Vòng nếu nhiều hơn để làm
.LOOP MOVS R1, R1, LSR # 1; Hãy đến cạnh 1 chút trong Carry
ADC R0, # 0; Thêm nó đếm
BNE LOOP; Vòng nếu nhiều hơn để làm
Các '' chương trình đếm số bit 1 trong R1 bằng cách chuyển chúng một chút tại một thời gian vào cờ carry và thêm các carry để R0. Nếu MOV để lại một khác không kết quả trong R1, các chi nhánh sẽ khiến hoạt động lặp lại (lưu ý rằng ADC không ảnh hưởng đến tình trạng như nó không có S tùy chọn).
Offsets và pipelining
Khi lắp ráp chuyển đổi một lệnh rẽ nhánh vào mã nhị phân thích hợp, nó tính toán bù đắp từ các hướng dẫn hiện hành đến địa chỉ đích. Việc bù đắp được mã hóa trong các từ lệnh như một địa chỉ từ 24-bit, như các máy tính trong R15. Đây được coi là một số chữ ký, và khi một chi nhánh được thực hiện bù đắp được thêm vào các máy tính hiện hành để đạt đến đích.
Tính toán bù là tham gia nhiều hơn một chút so với có lẽ bạn ít nghi ngờ đầu tiên - một lần nữa do pipelining. Giả sử vị trí của một lệnh rẽ nhánh là & 1230, và các nhãn đích là tại địa chỉ & 1288. Ngay từ cái nhìn đầu tiên nó xuất hiện các byte offset là & 1288- 1230 & = & 58 byte hay & 16 từ. Đây thực sự là sự khác biệt giữa các địa chỉ. Tuy nhiên, do thời gian ARM được vòng để thực hiện một lệnh, máy tính đã di chuyển hai hướng dẫn thêm về.
Với sự hiện diện của pipelining, bạn có thể thấy rằng do thời gian ARM bắt đầu thực hiện các chi nhánh tại & 1230, các máy tính có chứa & 1238, tức là địa chỉ của hai hướng dẫn cùng. Đây là địa chỉ này từ đó bù đắp cho những điểm đến phải được tính toán. Để hoàn thành ví dụ, lắp ráp thêm & 8 đến & 1230 để có được & 1238. Sau đó nó trừ này từ địa chỉ đích của & 1288 để có được bù đắp & 50 byte hay & 14 từ, đó là số thực sự được mã hóa trong hướng dẫn. May mắn là bạn không cần phải suy nghĩ về điều này khi sử dụng B hướng dẫn.
Chi nhánh có liên kết
Các biến thể duy nhất về chủ đề chi nhánh là tùy chọn để thực hiện một hoạt động liên kết trước khi chi nhánh được thực thi. Điều này đơn giản có nghĩa là lưu trữ các giá trị hiện tại của R15 trong R14 trước khi chi nhánh được thực hiện, do đó chương trình còn có một số cách để trở về đó. Chi nhánh có liên kết, BL , được sử dụng để thực hiện các thủ tục con, và thay thế thông thường hơn BSR (chi nhánh để chương trình con) và JSR (nhảy tới chương trình con) hướng dẫn tìm thấy trên một số máy tính.
Hầu hết các bộ vi xử lý thực hiện BSR bằng cách tiết kiệm địa chỉ trả về trên stack. Kể từ ARM không có chồng chuyên dụng, nó không thể làm điều này. Thay vào đó, bản R15 vào R14. Sau đó, nếu gọi là thói quen cần phải sử dụng R14 cho một cái gì đó, nó có thể lưu nó vào stack một cách rõ ràng. Phương pháp ARM có lợi thế mà các chương trình con mà không cần phải lưu R14 có thể được gọi và trở lại nhanh chóng. Nhược điểm là tất cả các thói quen khác có chi phí tiết kiệm một cách rõ ràng R14.
Các địa chỉ đó ARM tiết kiệm trong R14 là của lệnh ngay sau BL . (. Pipelining Given, nó nên là một sau đó, nhưng bộ xử lý tự động điều chỉnh giá trị lưu) Vì vậy, để trở về từ một chương trình con, chương trình chỉ cần có để di chuyển R14 trở lại vào R15:
MOVS R15, R14
Các phiên bản được hiển thị sẽ khôi phục lại những lá cờ ban đầu quá, tự động làm cho các chương trình con bảo tồn chúng. Nếu kết quả một số đã được chuyển lại vào sổ trạng, MOV mà không S có thể được sử dụng. Điều này sẽ chỉ chuyển phần PC của R14 trở lại R15, cho phép các chương trình con để vượt qua tình trạng thông tin trở lại trong những lá cờ.
BL có định dạng dự kiến:
BL {cond} <expression>
3.6 Nhóm năm - phần mềm gián đoạn
Nhóm cuối cùng là đơn giản nhất và phức tạp nhất. Nó rất đơn giản bởi vì nó có chứa chỉ là một hướng dẫn, SWI , dạng lắp ráp hoàn toàn không có các biến thể hoặc tùy chọn.
Dạng tổng quát của SWI là:
SWI {cond} <expression>
Nó phức tạp vì tùy thuộc vào <expression> , SWI sẽ thực hiện các nhiệm vụ khác nhau như hiển thị các ký tự trên màn hình, thiết lập tốc độ lặp lại tự động của bàn phím và tải một tập tin từ đĩa.
SWI là truy cập của người sử dụng cho hệ điều hành của máy tính. Khi một SWI được thực thi, các CPU vào chế độ giám sát, lưu địa chỉ trở lại trong R14_SVC, và nhảy đến vị trí 8. Từ đây, hệ điều hành mất hơn. Cách thức mà các SWI được sử dụng phụ thuộc vào <expression> . Điều này được mã hoá là một trường 24-bit trong hướng dẫn. Các hệ điều hành có thể kiểm tra hướng dẫn sử dụng, ví dụ :.
! STMFD R13, {R0-R12}; đăng ký của Lưu dùng
BIC R14, R14, # & FC000003; bit trạng thái Mask
LDR R13, [R14, # - 4]; Tải hướng dẫn SWI
BIC R14, R14, # & FC000003; bit trạng thái Mask
LDR R13, [R14, # - 4]; Tải hướng dẫn SWI
để tìm hiểu những gì <expression> là.
Kể từ khi giải thích <expression> phụ thuộc hoàn toàn vào hệ thống trong đó các chương trình được thực hiện, chúng tôi không thể nói nhiều hơn về SWI đây. Tuy nhiên, các chương trình như thực tế cần phải sử dụng các chức năng của hệ điều hành, các ví dụ trong các chương sau sẽ sử dụng một "tiêu chuẩn" thiết lập mà bạn có thể mong đợi một cách hợp lý. Hai trong số những người quan trọng nhất được gọi làWriteC và ReadC . Cựu gửi các nhân vật trong các byte cuối của R0 vào màn hình, và sau này đọc một ký tự từ bàn phím và trả về nó trong các byte cuối của R0.
Lưu ý: Các mã trong ví dụ trên sẽ được thực hiện trong SVC chế độ, do đó truy cập đến R13 và R14 là thực sự để R13_SVC và R14_SVC. Như vậy phiên bản của người sử dụng của các đăng ký không cần phải được lưu lại.
3,7 timings Instruction
Đó là thông tin để biết cách nhanh chóng như thế nào bạn có thể mong đợi lệnh để thực thi. Phần này cung cấp cho thời gian của tất cả các hướng dẫn ARM. Giờ được biểu diễn theo "chu kỳ". Một chu kỳ là đánh dấu một trong những tinh thể đồng hồ dao động mà ổ đĩa ARM. Trong thực tế có ba loại chu kỳ, gọi là tuần tự, không tuần tự và nội bộ.
Tuần tự (s) các chu kỳ là những người sử dụng để truy cập vào vị trí bộ nhớ thứ tự tuần tự. Ví dụ, khi ARM đang thực hiện một loạt các nhóm một hướng dẫn với không bị gián đoạn từ các chi nhánh và các hoạt động tải / cửa hàng, chu kỳ tuần tự sẽ được sử dụng.
Không tuần tự (n) chu kỳ được những người sử dụng để truy cập vào bộ nhớ bên ngoài khi địa điểm không liên tục được yêu cầu. Ví dụ, hướng dẫn đầu tiên được nạp sau khi một lệnh rẽ nhánh sẽ sử dụng một n-chu kỳ.
Internal (i) các chu kỳ là những người sử dụng khi ARM không truy cập vào bộ nhớ tại tất cả, nhưng thực hiện một số hoạt động nội bộ.
Trên một ARM điển hình, tốc độ đồng hồ là 8MHz (tám triệu chu kỳ một giây). chu kỳ S 125 nano giây cuối cùng cho bộ nhớ RAM và 250ns cho ROM. Tất cả n-chu kỳ là 250ns. Tất cả i-chu kỳ là 125ns trong thời hạn.
Hướng dẫn được bỏ qua do điều kiện không luôn luôn thực hiện trong 1s chu kỳ.
một nhóm
MOV , ADD , vv 1 s chu kỳ. Nếu <RHS> chứa một số thay đổi trong một đăng ký (tức là không phải là một sự thay đổi ngay lập tức), thêm 1 s chu kỳ. Nếu <ĐÍCH> là R15, thêm 1 s + 1 n-chu kỳ.
Nhóm một A
MUL , MLA . 1 s + 16 chu kỳ i- trường hợp xấu nhất.
nhóm hai
LDR . 1 s + 1 n + 1 i-chu kỳ. Nếu <ĐÍCH> là R15, thêm 1 s + 1N chu kỳ.
STR . 2 n-chu kỳ.
nhóm ba
LDM . (regs-1) s + 1 n + 1 i-chu kỳ. Regs là số đăng ký nạp. Thêm 1 s + 1 n-chu kỳ nếu R15 được tải.
STM . 2 n + (regs-1) của chu kỳ.
nhóm bốn
B , BL . 2 s + 1 n-chu kỳ.
nhóm năm
SWI . 2 s + 1 n-chu kỳ.
Từ những timings bạn có thể thấy rằng khi ARM thực hiện một số nhóm một hướng dẫn theo thứ tự, nó làm như vậy với tốc độ tám triệu một giây. Các phí gọi và trở về từ một chương trình con là 3 s + 1 n-chu kỳ, hoặc 0,525 micro giây nếu địa chỉ trả lại được lưu giữ, hoặc 2 s + 5 n-chu kỳ, hoặc 1.5μs nếu địa chỉ trả lại được xếp chồng lên nhau.
Một nhân bằng không hoặc một mất 125ns. Một trường hợp xấu nhất nhân mất 2.125μs. Tiết kiệm tám thanh ghi trên stack mất 7 s + 2 n-chu kỳ, hoặc 1.375μs. Đang tải chúng trở lại, nếu một trong số họ là các máy tính, mất 1,75 μ6s.
0 Comment:
Đăng nhận xét
Thank you for your comments!