THANH GHI Tập hợp các thanh ghi nằm trong BXL Chứa các thông tin tạm thời phục vụ cho hoạt động ở thời điểm hiện tại của BXL Như là mức đầu tiên của hệ thống nhớ Tùy thuộc vào BXL
Trang 1CHƯƠNG 4
MỨC VI LẬP TRÌNH
Trang 2THANH GHI
Tập hợp các thanh ghi nằm trong BXL
Chứa các thông tin tạm thời phục vụ cho hoạt động ở thời điểm hiện tại của BXL
Như là mức đầu tiên của hệ thống nhớ
Tùy thuộc vào BXL cụ thể
Số lượng thanh ghi nhiều → tăng hiệu năng của BXL
Có hai loại thanh ghi
Các thanh ghi lập trình được
Các thanh ghi không lập trình được
Trang 3THANH GHI
Một số thanh ghi điển hình
Các thanh ghi địa chỉ
Bộ đếm chương trình (Program Counter)
Con trỏ dữ liệu (Data Pointer)
Con trỏ ngăn xếp (Stack Pointer)
Thanh ghi cơ sở và thanh ghi chỉ số (Base Register & Index Register)
Các thanh ghi dữ liệu
Thanh ghi trạng thái (thanh ghi cờ)
Trang 4THANH GHI
Thanh ghi địa chỉ
Chương trình mã máy đang thực hiện chiếm 3
Trang 5THANH GHI
Bộ đếm chương trình
Còn gọi là con trỏ lệnh IP (Instruction Pointer), quản lý địa chỉ vùng lệnh
Giữ địa chỉ của lệnh tiếp theo sẽ được nhận vào
tăng để trỏ sang lệnh kế tiếp
Trang 6THANH GHI
Minh họa bộ đếm chương trình
.
Lệnh Lệnh Lệnh
Lệnh sẽ được nhận vào Lệnh kế tiếp Lệnh Lệnh
.
PC
Trang 7THANH GHI
Thanh ghi con trỏ dữ liệu
DP
Trang 8THANH GHI
Con trỏ ngăn xếp
Là vùng nhớ có cấu trúc LIFO
Đáy ngăn xếp là một ngăn nhớ xác định
Đỉnh ngăn xếp có thể bị thay đổi
SP trỏ vào ngăn nhớ đỉnh ngăn xếp
Cất thêm thông tin vào ngăn xếp → SP giảm
Lấy thông tin từ ngăn xếp → SP tăng
Khi ngăn xếp rỗng → SP trỏ vào đáy
Trang 10THANH GHI
(ngăn nhớ gốc tương đối), còn gọi: địa chỉ đoạn
(segment)
Thanh ghi chỉ số: chứa độ lệch của địa chỉ giữa
ngăn nhớ mà BXL cần truy nhập so với ngăn nhớ
cơ sở, còn gọi: địa chỉ offset
Trang 11Thanh ghi chỉ số
Khoả ng lệ
ch
Trang 12 Các thanh ghi dữ liệu
Chứa các dữ liệu tạm thời hoặc kết quả trung gian
Cần có nhiều thanh ghi dữ liệu
Các thanh ghi số nguyên: 8, 16, 32, 64, Bit
Trang 13 Thanh ghi trạng thái
Còn gọi là thanh ghi cờ (Flag Register)
Chứa các thông tin trạng thái của BXL
Các cờ phép toán: báo hiệu trạng thái của phép toán
Các cờ điều khiển: biểu thị trạng thái điều khiển của BXL
Trang 14Minh họa thanh ghi trạng thái
Cờ trạng thái
Cờ điều khiển
• OF (Overflow - tràn): OF = 1 xác định tràn số học, xảy ra khi kết quả vượt ra ngoài phạm
vi biểu diễn
• DF (Direction- hướng): xác định hướng chuyển chuỗi, DF = 1 khi CPU làm việc với chuỗi
theo thứ tự từ phải sang trái và ngược lại
• IF (Interrupt - ngắt): cho phép hay cấm các ngắt có mặt nạ.
• TF (Trap - bẫy): đặt CPU vào chế độ từng bước, dùng cho các chương trình gỡ rối
(debugger)
• SF (Sign - dấu): dùng để chỉ các kết quả số học là số dương (SF = 0) hay âm (SF = 1).
• ZF (Zero): = 1 nếu kết quả của phép toán trước là 0.
• AF (Auxiliary – nhớ phụ): dùng trong các số thập phân để chỉ nhớ từ nửa byte thấp hay
mượn từ nửa byte cao
• PF (Parity): PF = 1 nếu kết quả của phép toán là có tổng số bit 1 là chẵn (dùng để kiểm tra
lỗi truyền dữ liệu)
•CF (Carry): CF = 1 nếu có nhớ hay mượn từ bit cao nhất của kết quả Cờ này cũng dùng
cho các lệnh quay
Trang 154.2.1 Đường dữ liệu
Đường dữ liệu là một phần của CPU, nó có chứa
ALU, các đầu vào và đầu ra
Thí dụ trên hình vẽ:
16 thanh ghi 16 bit giống nhau tạo nên một bộ
nhớ tạm chỉ truy cập được ở mức vi chương
trình
Thanh ghi đưa nội dung ra: bus A, bus B hoặc
đồng thời cả 2 bus
Nạp vào thanh ghi: từ bus C
ALU (16 bit) có thể thực hiện 4 chức năng: A+B,
A AND B, A và not A
F0 và F1 định chức năng sẽ được ALU thực
hiện
ALU sinh ra hai bit trạng thái dựa trên kết quả ra
hiện thời của nó:
N có giá trị 1 khi kết quả ra là âm
Z có giá trị 1 khi kết quả ra bằng 0 (Zê-rô)
A
Trang 164.2.1 Đường dữ liệu (Data path)
Shifter có thể dịch: trái, phải, không dịch
Có thể thực hiện dịch trái hai bit một giá
trị ghi trong thanh ghi R, bằng cách tính
R+R trong ALU, sau đó dịch kết quả
(tổng) một bit nữa sang trái bằng thanh
ghi dịch.
A latch và B latch: được nạp từ bus A và
bus B để cho phép có thể thay đổi nội
dung các thanh ghi đã nạp giá trị vào
ALU.
Các tín hiệu L0 và L1 điều khiển việc nạp
giá trị trên bus A và bus B vào các thanh
ghi chốt.
Trang 174.2.1 Đường dữ liệu (Data path)
MAR: thanh ghi địa chỉ ô nhớ cần thao tác
Có thể được nạp từ thanh ghi chốt B song
song với một thao tác của ALU
M0 điều khiển việc nạp của MAR
MBR: thanh ghi đệm (dữ liệu) đọc/ghi bộ nhớ
Được nạp giá trị từ đầu ra của thanh ghi
dịch, giá trị này cũng có thể đồng thời được
chứa vào một trong các thanh ghi của bộ
nhớ tạm
M1 điều khiển việc nạp của MBR từ đầu ra
của thanh ghi dịch
M2 và M3 điều khiển việc đọc và ghi bộ nhớ
AMUX: bộ dồn kênh để chọn dữ liệu đưa vào
ALU từ A latch hay từ MBR
A0 điều khiển AMUX
Trang 184.4.2 Thí dụ về một vi chương trình
Các thanh ghi:
PC, AC và SP
IR: Thanh ghi lệnh
TIR (Temporary IR): chứa tạm thời bản sao của
IR dùng để giải mã vĩ chỉ thị
0, 1, -1: các hằng số được chỉ ra trên thanh ghi
AMASK ( 0000.1111.1111.1111b): làm mặt nạ để
tách các bit của trường địa chỉ khỏi các bit của
trường opcode trong chỉ thị MAC-1
SMASK ( 0000.0000.1111.1111b): làm mặt nạ để
tách địa chỉ offset 8 bit trong các chỉ thị INSP và
DESP
Sáu thanh ghi còn lại (A, B, C, D, E, F) không
được gán trước các chức năng, có thể được sử
Trang 19 2 tín hiệu để điều khiển chức năng ALU.
2 tín hiệu để điều khiển bộ dịch.
4 tín hiệu để điều khiển MAR và MBR.
2 tín hiệu để chỉ rõ thao tác đối với bộ nhớ
(R/W).
1 tín hiệu để điều khiển Amux.
Tổng số tín hiệu: 61
Trang 204.2.2 Vi chỉ thị - microinstruction
Có thể điều khiển đường dl bằng 61 tín hiệu
Thực hiện một chu kỳ của đường dữ liệu:
Một chu kỳ bao gồm việc mở cổng cho
các giá trị trong bộ nhớ tạm đi vào bus A
và bus B, chốt chúng lại trong hai thanh
ghi chốt bus A latch và B latch
Cho các giá trị từ các thanh ghi chốt chạy
qua ALU và shifter
Cuối cùng là việc chứa các kết quả vào
trong bộ nhớ tạm hoặc vào MBR Ngoài
ra MAR cũng có thể được nạp, sau đó
Trang 214.2.2 Vi chỉ thị - microinstruction
Giảm số bít để điều khiển đường dữ liệu:
Sử dụng bộ giải mã 4 -16: giảm số bit điều khiển mỗi bus A, B và C từ 16 xuống còn 4.
Chấp nhận chỉ nạp dữ liệu trên bus C vào 1 trong 16 thanh ghi.
Trang 224.2.2 Vi chỉ thị: khuôn dạng gồm 13 trường
Trang 234.2.3 Việc định thời vi chỉ thị
Là việc định trình tự xảy ra các sự kiện trong quá
trình thực hiện một vi chỉ thị
Một chu kỳ ALU cơ sở bao gồm việc:
1. Nạp vi chỉ thị tiếp theo sẽ được thi hành vào
MIR
2. Mở cổng các thanh ghi tạm đi vào bus A và
bus B và giữ chúng trong A latch và B latch
3. Khi các giá trị đưa vào ALU ổn định, dành
thời gian cho ALU và shifter để chúng sinh ra giá trị ra ổn định; nạp MAR nếu cần thiết
4. Khi giá trị ra của shifter ổn định, chứa giá trị
trên bus C vào bộ nhớ tạm và nạp cho MBR nếu việc này cũng được yêu cầu
sử dụng một đồng hồ 4 pha (có 4 chu kỳ con)
Trang 254.2.3 Việc định
thời vi chỉ thị
Chu kỳ con thứ hai: Đơn
vị Increment tính MPC+1;
Các trường của MIR bắt
đầu điều khiển đường dữ
Trang 26nhánh trái của ALU
Trong khi ALU và
shifter đang tính toán
thì MAR được nạp từ
bus B nếu trường
MAR =1.
Trang 274.2.3 Việc định
thời vi chỉ thị
Chu kỳ con thứ tư:
Giá trị trên bus C có thể được
Nếu 2 tín hiệu đầu tiên đồng
thời =1, C decoder sẽ giải mã
chọn 1/16 thanh ghi
Hai tín hiệu điều khiển bộ nhớ RD
và WR được nối với các bit tương
ứng của MIR
Trang 281 = Nhảy tới ADDR nếu N =1
2 = Nhảy tới ADDR nếu Z =1
3 = Nhảy tới ADDR vô điều
kiện.
Trang 294.2.4 Sự định trình tự các vi chỉ thị
và 2 bit L (Left - trái) và bit R (Right - phải) của trường
COND để sinh ra tín hiệu điều khiển Mmux.
R L
Trang 304.3 Thí dụ về một kiến trúc mức máy thông thường
Để nghiên cứu tiếp thí dụ về mức vi chương trình, chúng ta cần nghiên cứu kiến trúc của mức máy thông thường, mức này sẽ được hỗ trợ bởi một trình thông dịch chạy trên máy mức 1 - Mức Vi chương trình.
4.3.1 Kiến trúc mức máy thông thường - Vĩ kiến trúc 4.3.2 Vấn đề đánh địa chỉ bộ nhớ chính và bộ nhớ ngăn xếp
4.3.3 Tập vĩ chỉ thị
Trang 314.3.1 Kiến trúc mức máy thông thường - Vĩ kiến trúc
Vi chương trình.
(macroarchitecture) cho tương phản với kiến trúc ở mức 1
đã được gọi là vi kiến trúc (microarchitecture) Gọi máy
mức 2 là Mac-1.
MOVE và các chỉ thị khác của mức máy thông thường (máy mức 2) sẽ được gọi là vĩ chỉ thị.
Trang 324.3.2 Vấn đề đánh địa chỉ bộ nhớ chính và
bộ nhớ ngăn xếp
Sự cần thiết phải có stack:
Sử dụng cho các biến cục bộ của các chương trình con
Cần tổ chức theo kiểu LIFO (Last In First Out).
Cần một con trỏ đỉnh stack - SP (Stack Pointer).
2 thao tác quan trọng nhất là PUSH và POP
PUSH X: dịch con trỏ stack rồi đặt X vào bộ nhớ tại vị trí lúc này được trỏ bởi SP.
POP Y: chứa phần tử ở trên cùng của stack vào Y rồi dịch con trỏ.
Trang 332 Tại mức máy thông thường chúng ta sử dụng 3 thanh ghi là:
PC (Program Counter): con trỏ lệnh, trỏ tới lệnh sắp được thực hiện
SP (Stack Pointer): được sử dụng cho các thao tác với bộ nhớ stack
AC (ACcumulator): cho các thao tác với bộ nhớ (vận chuyển dữ liệu,
để tính toán số học )
vị trí của dữ liệu (toán hạng, chỉ thị của chương trình).
Trang 344.3.2 Vấn đề đánh địa chỉ bộ nhớ chính và
bộ nhớ ngăn xếp
Các chỉ thị mode địa chỉ trực tiếp: có chứa một địa chỉ bộ nhớ
12 bit, đánh được địa chỉ của toàn bộ 4096 từ trong bộ nhớ
Những chỉ thị như vậy cần phải có để truy cập các biến toàn cục.
Các chỉ thị mode gián tiếp: (12 bit) cho phép người lập trình tính
địa chỉ nhớ, đặt nó vào trong thanh ghi AC, sau đó đọc hoặc ghi word đã được đánh địa chỉ Dạng đánh địa chỉ này rất phổ biến và thường được dùng để truy cập các phần tử của mảng.
Các chỉ thị mode cục bộ: (có thể <= 12 bit) chỉ ra một vị trí
tương đối (độ dịch hay offset) so với SP và được dùng để truy cập các biến cục bộ
Trang 354.3.2 Vấn đề đánh địa chỉ bộ nhớ chính và
bộ nhớ ngăn xếp
LODD, STOD, ADDD, SUBD: sd mode địa chỉ trực tiếp
LODL, STOL, AD, DL, SUBL sd mode địa chỉ cục bộ
JUMP: chỉ thị nhảy không điều kiện
JPOS, JZER, JNEG, JNZE: nhảy có điều kiện
LOCO: nạp 1 hằng số 12 bit vào AC
PSHI: đẩy word có địa chỉ nằm trong AC lên stack
POPI: Lấy 1 word ra khỏi stack và chứa nó vào một word của bộ nhớ có địa chỉ nằm trong AC
SWAP: hoán vị nội dung AC và SP
INSP, DESP: thay đổi SP một lượng đã biết trong lúc biên dịch
Call: gọi thủ tục sau khi đã cất địa chỉ trở về vào stack
Trang 364.3.3 Tập vĩ chỉ thị
Mã nhị phân (Binary) (Mnemonic) Ký hiệu Thực hiện Giải thích
Trang 374.3.3 Tập vĩ chỉ thị
Mã nhị phân (Binary) (Mnemonic) Ký hiệu Thực hiện Giải thích
1100xxxxxxxxxxxx JNEG Jump negative if ac < 0 then pc:=x 1101xxxxxxxxxxxx JNZE Jump nonzero if ac <> 0 then pc:=x
Trang 384.3.3 Tập vĩ chỉ thị
Mã nhị phân (Binary) (Mnemonic Ký hiệu
)
Thực hiện Giải thích
1110xxxxxxxxxxxx CALL Call procedure sp:=sp-1; m[sp]:=pc; pc:=x
1111000000000000 PSHI Push indirect sp:=sp-1; m[sp]:=m[ac]
1111001000000000 POPI Pop indirect m[ac]:=m[sp]; sp:=sp+1
1111010000000000 PUSH Push onto stack sp:=sp-1; m[sp]:=ac
1111011000000000 POP Pop from stack ac:=m[sp]; sp:=sp+1
Trang 394.4.1 Ngôn ngữ Vi assembly
Để chỉ rõ việc sử dụng các chức năng 0, 1, 2 và 3
của ALU, chúng ta viết:
ac:=a+ac a:=band(ir,smask) ;# band = "Boolean and“ ac:=a
a:=inv(a) ;# inv = “invert”
Các thao tác dịch trái và dịch phải có thể được ký
hiệu là lshift và rshift, như:
tir:=lshift(tir+tir)
Trang 40C O N D
A L U
S H
M B R
M A R
R D
W R
E N
C C B A
A D D R
Mar := pc; rd 0 0 2 0 0 1 1 0 0 0 0 0 00
Rd 0 0 2 0 0 0 1 0 0 0 0 0 00
ir := mbr 1 0 2 0 0 0 0 0 1 3 0 0 00
pc := pc+1 0 0 0 0 0 0 0 0 1 0 6 0 00
Mar := ir; mbr := ac; wr 0 0 2 0 1 1 0 1 0 0 3 1 00
alu := tir; if n then goto 15 0 1 2 0 0 0 0 0 0 0 0 4 15
ac := inv (mbr) 1 0 3 0 0 0 0 0 1 1 0 0 00
tir := lshift (tir); if n then goto 25 0 1 2 2 0 0 0 0 1 4 0 4 25
alu := ac; if z then goto 22 0 2 2 0 0 0 0 0 0 0 0 1 22
ac :=band(ir, amask); goto 0 0 3 1 0 0 0 0 0 1 1 8 3 00
sp := sp + (-1); rd 0 0 0 0 0 0 1 0 1 2 2 7 00
tir := lshift(ir+ir); if n then goto
Trang 414.4.2 Thí dụ về một vi chương trình
Giống mọi chương trình thông dịch, vi chương trình của chúng ta có một vòng lặp chính:
Lấy chỉ thị về (fetch): bắt đầu từ dòng 0
Giải mã (decode): dòng 2-5 (đây là một trong các nhánh)
Thi hành (execute): dòng 6-8 (đây là một trong các nhánh, thực hiện LODD)
0: mar := pc; rd; {main loop Fetch an Instruction}
1: pc := pc+1; rd; {increment pc, and keep on reading}
2: ir := mbr; if n then goto 28; {save, if opcode = 1xxx.12x then goto 28}
3: tir :=lshift(ir+ir); if n then goto 19; {if opcode = 01xx.12x then goto 19 else next line}
4: tir := lshift(tir); if n then goto 11; {000x or 001x?}
5: alu := tir; if n then goto 9; {0000 or 0001?}
Trang 424.4.2 Thí dụ về một vi chương trình
0: mar := pc; rd; {main loop Fetch an Instruction}
1: pc := pc+1; rd; {increment pc, and keep on reading} 2: ir := mbr; if n then goto 28; {save, if opcode = 1xxx.12x then goto 28}
3: tir :=lshift(ir+ir); if n then goto 19; {if opcode = 01xx.12x then goto 19 else
next line}
4: tir := lshift(tir); if n then goto 11; {000x or 001x?}
5: alu := tir; if n then goto 9; {0000 or 0001?}
{ ↓ opcode = 0001.12x - STOD - ↓ }
9: mar := ir; mbr := ac; wr; {STOD: mar := operand add, and write}
10: wr; goto 0; {keep on writing, going to fetch a next instruction}
Trang 434.4.2 Thí dụ về một vi chương trình
0: mar := pc; rd; {main loop Fetch an Instruction}
1: pc := pc+1; rd; {increment pc, and keep on reading} 2: ir := mbr; if n then goto 28; {save, if opcode = 1xxx.12x then goto 28} 3: tir :=lshift(ir+ir); if n then goto 19; {if opcode = 01xx.12x then goto 19
else next line}
4: tir := lshift(tir); if n then goto 11; {000x or 001x?}
{ ↓ opcode = 001x.12x - ADDD or SUBD - ↓ }
11: alu := tir; if n then goto 15; {0010 or 0011?}
Trang 444.4.2 Thí dụ về một vi chương trình
0: mar := pc; rd; {main loop Fetch an Instruction}
1: pc := pc+1; rd; {increment pc, and keep on reading}2: ir := mbr; if n then goto 28; {save, if opcode = 1xxx.12x then goto 28}
3: tir :=lshift(ir+ir); if n then goto 19; {if opcode = 01xx.12x then goto 19 else next line}4: tir := lshift(tir); if n then goto 11; {000x or 001x?}
{↓opcode = 001x.12x - ADDD or SUBD -↓}
11: alu := tir; if n then goto 15; {0010 or 0011?}
{↓opcode = 0011.12x - SUBD -↓}
15: mar := ir; rd; {SUBD: mar := operand add, and read}
16: ac := ac + 1; rd; {keep on reading while executing ac := ac+1}
17: a := inv(mbr); {Note: x - y = x + 1 + not y}
18: ac := ac + a; goto 0; {ac := ac+not.m[x] + 1; going to fetch a next instruction}
Trang 454.4.2 Thí dụ về một vi chương trình
0: mar := pc; rd; {main loop Fetch an Instruction}
1: pc := pc+1; rd; {increment pc, and keep on reading} 2: ir := mbr; if n then goto 28; {save, if opcode = 1xxx.12x then goto 28}
3: tir :=lshift(ir+ir); if n then goto 19; {if opcode = 01xx.12x then goto 19
else next line}
{ ↓ opcode = 01xx.12x - ↓ }
19: tir := lshift(tir); if n then goto 25; {if opcode = 011x.12x then goto 25 else next line}
20: alu := tir; if n then goto 23; {if opcode = 0101.12x then goto 23 else next line}
{ ↓ opcode = 0100.12x - JPOS - ↓ }
21: alu := ac; if n then goto 0 {JPOS: if ac < 0 then going to jump}
22: pc := band(ir, amask); goto 0; {calc add to jump, and perform the jump}
{ ↑ - JPOS - ↑ }