2011-10-24 30 views
7

Dưới đây là một số mã lắp ráp MIPS tôi đã viết để kiểm tra hướng dẫn nhảy:Jump hướng dẫn trong MIPS hội

addi $a0, $0, 1 
j next 
next: 
j skip1 
add $a0, $a0, $a0 
skip1: 
j skip2: 
add $a0, $a0, $a0 
add $a0, $a0, $a0 
skip2: 
j skip3 
loop: 
add $a0, $a0, $a0 
add $a0, $a0, $a0 
add $a0, $a0, $a0 
skip3: 
j loop 

Khi tôi chạy lắp ráp, đây là kết quả:

[0x000000] 0x20040001 # addi $a0, $zero, 1 ($a0 = 1) 
[0x000004] 0x08000002 # j 0x0002 (jump to addr 0x0008) 
[0x000008] 0x08000004 # j 0x0004 (jump to addr 0x0010) 
[0x00000C] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0) 
[0x000010] 0x08000007 # j 0x0007 (jump to addr 0x001C) 
[0x000014] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0) 
[0x000018] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0) 
[0x00001C] 0x0800000B # j 0x000B (jump to addr 0x002C) 
[0x000020] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0) 
[0x000024] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0) 
[0x000028] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0) 
[0x00002C] 0x08000008 # j 0x0008 (jump to addr 0x0020) 

Nhìn vào máy mã cho hướng dẫn nhảy, đây là những gì tôi thấy:

1st jump (just jumps to next instruction) 0x08000002 
2nd jump (skips 1 instruction) 0x08000004 
3rd jump (skips 2 instructions) 0x08000007 
4th jump (skips 3 instructions) 0x0800000B 
5th jump (skips 3 instructions backwards) 0x08000008 

Từ khi xem các hướng dẫn này, có vẻ như ike mã máy bắt đầu với số 08 cho lệnh nhảy và số ở cuối cho biết lệnh nhảy ở đâu. Tuy nhiên, tôi không thể tìm ra cách tính số này. Ngoài ra, không có gì để chỉ cho tôi rằng bước nhảy thứ 5 là một bước nhảy lùi.

Giá trị nhảy được tính như thế nào?

+0

tại sao bạn sử dụng 3 'thêm $ a0, $ a0, $ a0'? tại sao không sử dụng 'sll $ a0, $ a0, 3' –

Trả lời

12

Chỉ cần nhìn vào sổ tay tham khảo để biết thêm chi tiết về mã hóa opcode.

Phiên bản ngắn: Trong hướng dẫn 32 bit, bạn không thể bao gồm đích nhảy 32 bit. Opcode sử dụng 6 bit, để lại 26 bit cho lệnh. Địa chỉ đích được xây dựng bằng cách lấy 4 bit đầu tiên của địa chỉ của lệnh sau lệnh j, sau đó 2 bit không được nối vào 26 bit từ toán hạng lệnh nhảy. (Theo hướng dẫn là 32 bit, căn chỉnh là hữu ích và cho phép bỏ qua hai số 0 cuối cùng.)

Để nhảy lùi: Địa chỉ tuyệt đối, KHÔNG tương đối, vì vậy nó chỉ phụ thuộc vào địa chỉ của lệnh nhảy , cho dù đó là một bước tiến hay lùi.

EDIT: Mô tả chi tiết hơn: Chúng tôi có tại địa chỉ x nhảy hướng dẫn j. Hãy để t thể hiện toán hạng nhảy của j. t rộng 26 bit. Các mẫu bit của địa chỉ của lệnh tiếp theo được tính như sau:

upper_6_bits_of(x+4),t,0,0 

Vì vậy, các bước nhảy là LUÔN tuyệt đối. Không có bước nhảy tương đối. khi kết quả nhỏ hơn x thì nó là một bước nhảy lùi, khi nó lớn hơn nó là một bước nhảy về phía trước (và nếu bạn muốn một cái gì đó ngu ngốc, bạn làm cho nó bằng nhau ;-).

Vì vậy, chúng ta hãy nhìn vào những bước nhảy thứ 5 của ví dụ của bạn:

6 bit đầu tiên của mục tiêu nhảy là: 000000, bởi vì phía trên 6 bit của địa chỉ của lệnh sau khi nhảy là 000000.

26 bit tiếp theo là 26 bit thấp nhất của lệnh nhảy, đó là 00000000000000000000001000

2 bit cuối cùng là: 00, vì luôn được nối.

Cùng nhau chúng ta có: 0000000000000000000000000000100000, đó là hex 20. Và tại địa chỉ đó chính xác là nhãn/hướng dẫn nơi luồng sẽ tiếp tục.

+0

Điều này không trả lời câu hỏi về cách địa chỉ tương đối chỉ định một bù đắp ngược. Thông thường, giá trị tương đối jmp sẽ là tiêu cực để thực hiện điều này. Ngoài ra, các phần bù ở trên không có ý nghĩa nhiều cho các bước nhảy. Tôi, giống như @ z-buffer, cũng hơi bối rối bởi việc tháo gỡ ... –

+0

Chỉnh sửa của bạn giải thích bước nhảy là tuyệt đối, nhưng bù lại vẫn không thực sự xếp hàng. Phải có cái gì đó khác đang diễn ra ở đây. +1 vẫn trả lời câu hỏi hoàn chỉnh. –

+2

@Michael Dorgan: Các bước nhảy ngược lại là tốt vì nó là: Nó cho thấy là ... 08. Điều đó 08 trái chuyển bởi hai (hai 2 số không tôi đã đề cập) là 32 đó là hex 0x20. Và hướng dẫn nơi nhảy đi là 0x..20. Vì vậy, nó phù hợp hoàn hảo (cùng với 4 bước nhảy khác). – flolo

6

Trong MIPS, J là một hướng dẫn J-type:

J-type instructions (Jumps) 
3 22 
1 65      0 
+----+-------------------------+ 
| op |   target   | 
+----+-------------------------+ 

Vì vậy, chúng tôi có một target đó là dài 26-bit. Nó được kết hợp với máy tính của lệnh tiếp theo như sau:

I 
I+1 PC <- (PC & 0xf0000000) | (target << 2) 

nó được chuyển trái 2 bit, vì hướng dẫn MIPS (bỏ qua phần mở rộng MIPS16) dài 32-bit, có nghĩa là tất cả họ đều bắt đầu trong một địa chỉ mà 2 bit thấp hơn là 0.

+0

Một cách khác để nghĩ về nó là, giá trị nonzero nhỏ nhất mà bạn có thể đưa vào hướng dẫn nhảy là gì? Đó sẽ là 1 và tương ứng với lệnh 2 trong chương trình, ở mức 0x4. Vì vậy, về cơ bản đó là một bước nhảy đến địa chỉ tuyệt đối của lệnh, chia cho 4, vì các địa chỉ là lệnh thứ n luôn luôn (n-1) * 4. Để chia cho 4, bạn di chuyển sang phải bằng 2 bit vì việc dịch bit n phải chia số cho (2^n). –