Tải bản đầy đủ (.docx) (28 trang)

Tiểu luận tổ chức bộ nhớ và lập trình bằng ngôn ngữ assembly

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.64 MB, 28 trang )

Đề tài:
Tổ chức bộ nhớ và lập trình bằng ngôn ngữ assembly
Giảng viên: Bùi Công Trường
Lớp:DHTH5A
Nhóm đề tài: nhóm 8
Tên MSSV
Hà Đình Sử 09219411
Phạm Thắng 09206671
Nguyễn Quang Minh 09220461Tổ chức bộ nhớ và
ngôn ngữ lập trình assembly
Mục tiêu:
Khi hoàn thành bài này, bạn sẽ có thể:
o Mô tả một hệ bộ nhớ tiêu biểu được tổ chức dưới dạng địa chỉ bộ nhớ như thế nào
o Mô tả mối quan hệ giữa một kiến trúc tập lệnh của máy tính và tập lệnh hợp ngữ; Và
o Sử dụng những cách đánh địa chỉ đơn giản để viết một chương trình hợp ngữ đơn giản.
Lời mở đầu
Bài học này sẽ bắt đầu quá trình chuyển đổi từ nhà thiết kế phần cứng sang các kỹ sư phần mềm.
Chúng tôi sẽ đem những gì chúng tôi đã tích lũy về hành vi của phần cứng để cho thấy được nó có
mối liên quan như thế nào đến kiến trúc tập lệnh (ISA) của một bộ vi xử lý điển hình. Nghiên cứu
của chúng tôi về kiến trúc sẽ giúp được các nhà phát triển phần mềm hiểu rõ những kiến trúc để phát
huy những lợi ích tốt nhất của nó. Trong ý nghĩa đó, nghiên cứu của chúng tôi về ngôn ngữ assembly
sẽ là một ẩn dụ cho việc nghiên cứu các kiến trúc của máy tính. Quan điểm này là khác biệt với
những người muốn có khả năng thiết kế phần cứng máy tính. Nội dung xuyên suốt trong cuốn sách
này của chúng tôi đã được dựa trên sự hiểu biết về phần cứng và các vấn đề kiến trúc để phát triển
phần mềm bổ sung cho việc thiết kế các phần cứng phía dưới.
Chúng tôi đang đi tiên phong nghiên cứu kiến trúc của các bộ vi xử lý Motorola 68.000. ISA 68K là
một kiến trúc hoàn chỉnh đầu tiên, xuất sưởng vào đầu những năm 1980. Đó sẽ là một câu hỏi công
bằng nếu hỏi: "Tại sao tôi lại học tập với một kiến trúc máy tính cũ? Có phải nó đã lỗi thời không? ".
Câu trả lời vang dội là: " Không! "Kiến trúc 68K là một trong những kiến trúc máy tính phổ biến
nhất của mọi thời đại và ứng dụng nền tảng 68K vẫn còn đang được thiết kế sản phẩm mới vào mọi
thời điểm. Palm PDA vẫn sử dụng một bộ xử lý 68K phái sinh. Ngoài ra, một bộ xử lý hoàn toàn


mới từ Motorola, các dòng ColdFire ®, sử dụng kiến trúc 68K, và ngày hôm nay, nó là một trong
những bộ vi xử lý phổ biến nhất được sử dụng. Ví dụ, ColdFire được sử dụng trong hầu hết các máy
in phun.
Trong chương tiếp theo, chúng tôi cũng sẽ giới thiệu sự khác biệt giữa hai kiến trúc phổ biến, các bộ
vi xử lý dòng Intel ® X86 và dòng ARM. Với những bộ vi xử lý theo kiến trúc vành đai ba lớp,
chúng ta sẽ được làm quen với máy tính phổ biến nhất trên thế giới ngày nay. Phần lớn những gì
chúng tôi sẽ thảo luận khi chúng tôi bắt đầu nghiên cứu sẽ được dùng chung cho cả 3 dòng bộ vi xử
lý, vì thế việc học tập là một trong những kiến trúc tốt cũng như một khi đạt được sự hiểu biết về các
nguyên tắc cơ bản.
Một lý do khác để bắt đầu với 68000 là kiến trúc phù hợp với quá trình học tập. Địa chỉ bộ nhớ khá
đơn giản và từ quan điểm của nhà phát triển phần mềm. Mối liên kết với các ngôn ngữ cấp cao dễ
dàng để hiểu.
Chúng tôi sẽ bắt đầu bằng cách nhìn lại vào mô hình bộ nhớ và sử dụng như là một bước nhảy ra cho
chúng tôi nghiên cứu các cách thức máy tính thật sự đọc và ghi vào bộ nhớ. Từ khía cạnh phần
cứng, chúng tôi đã nắm bắt được vì chúng tôi vừa hoàn thành việc nghiên cứu về nó, nhưng bây giờ
chúng tôi sẽ nhìn về khía cạnh ISA. Xuyên suốt quá trình, chúng tôi sẽ xem tại sao sự kì lạ thường
xuyên này của cách nhìn vào bộ nhớ thật sự là rất quan trọng từ điểm nhìn của ngôn ngữ cấp cao
hơn, chẳng hạn như C và C++. Thưa các bạn, bắt đầu khởi động …
Quy ước lưu trữ bộ nhớ
Khi bắt đầu nhìn từ cấp độ kiến trúc bạn sớm nhận ra rằng mối quan hệ giữa bộ xử lí và bộ nhớ là
một yếu tố quan trọng để xác định hành vi và hoạt động đặc trưng của máy. Nhiều máy tính thật sự
hoàn thành nó, công việc lập trình xung quanh giao diện của nó vào bộ nhớ. Vì thế bạn sẽ sớm thấy
khi chúng tôi bắt đầu từ chương trình trong ngôn ngữ assembly, hầu hết các máy tính làm việc đều
liên quan tới việc di chuyển dữ liệu trong và ngoài bộ nhớ. Thực ra nếu bạn tạo biểu đồ cột của
hướng dẫn ngôn ngữ assembly được sử dụng trong một chương trình, dù chương trình ban đầu được
viết bằng ngôn ngữ C++ hay assembly, bạn sẽ tìm thấy hướng dẫn sử dụng là MOVE hướng dẫn. Vì
vậy, một trong những bài đầu tiên của chúng tôi kinh doanh là xây dựng trên sự hiểu biết của chúng
tôi như thế nào về tổ chức hệ thống bộ nhớ và nhìn vào hệ thống bộ nhớ từ các tiềm năng của các bộ
vi xử lý.
Hình 7.1 là bản đồ cho bộ nhớ của bộ xử lí 68K. Bộ xử lí có thể một địa chỉ 16.777.216 (16-M) bye

của bộ nhớ. Nó có 23 dòng chữ địa chỉ bên ngoài và 2 byte selecter điều khiển tín hiệu để lựa chọn
một hoặc khác của 2 bye lưu trữ trong từ xác định. Bus dữ liệu ngoài là 16 bit rộng, nhưng đường dữ
liệu bên trong là cả 12 bit rộng. Tiếp theo thành viên của gia đình 68K, bắt đầu với 68020, tất cả có
32 bit dữ liệu ngoài. Trong hình 7.1 chúng ta thấy, đầu tiên 128K từ (128 bit) của bộ nhớ từ dãy
0x000000 đến 0x01FFFE. Vùng này điển hình là mã chương trình và những vùng vectơ. Hiểu
thoáng qua, vùng đọc/ghi của bộ nhớ là nơi mà các biến được lưu trữ. Phần còn lại của không gian
bộ nhớ chứa địa chỉ của I/O cho các thiết bị. Tất cả các phần còn lại của bộ nhớ trong hình 7.1 là
không gian trống rỗng. Ngoài
ra, chúng ta sẽ thấy lý do tại
sao trong một thời điểm các
địa chỉ cho từ cuối cùng của
ROM và từ cuối cùng của
RAM tương ứng là
0x01FFFE và 0xFFFFFE.
Kể từ thế hệ 8 bit hoặc 1
byte, nó là dung lượng lưu
trữ nhỏ nhất mà chúng tôi sử dụng, điều đó cũng dễ hiểu khi chúng tôi đang phải làm việc trên
những bộ nhớ cũng có 8 bit. Tuy nhiên, tất cả máy tính của chúng tôi đều có độ rộng vùng nhớ là 32
bit và rất nhiều máy tính được sử dụng ngày nay có độ rộng 16 bit đường dẫn dữ liệu. Như một ví dụ
cực đoan, chúng tôi không muốn lãng phí 24 bit của không gian lưu trữ, đơn giản chỉ vì chúng tôi
muốn lưu giữ một số lượng 8-bit trong một bộ nhớ 32-bit, do đó, các máy tính được thiết kế để cho
phép địa chỉ byte. Điều đó có nghĩa là địa chỉ byte trong một từ 32-bit như là một ví dụ về phân
trang với địa chỉ trang từ 32-bit và bù đắp được trong bốn vị trí byte có thể trong trang. Tuy nhiên,
có một sự khác biệt lớn giữa địa chỉ byte và phân trang thực sự. Với địa chỉ byte, chúng tôi không có
địa chỉ từ riêng biệt mà tương ứng với một địa chỉ trang. Hình 7,2 cho thấy sự khác biệt này rất quan
trọng.
Chúng tôi gọi đây là loại bộ nhớ lưu trữ byte đóng gói vì chúng ta là nghĩa đen đóng gói đầy đủ 32-
bit bộ nhớ vào 1 byte. Loại địa chỉ này giới thiệu một vài sự mơ hồ. Một, là khá nghiêm trọng, và
mọi thứ khác là mới đối với chúng tôi. Chúng tôi sẽ thảo luận về sự nghiêm trọng này trong giây lát.
Căn cứ theo hình 7,2 chúng ta thấy rằng lúc địa chỉ bộ nhớ byte FFFFF0 (char) và từ 32-bit dài (int)

tại FFFFF0 có cùng địa chỉ. Có phải là thảm họa này đang chờ để xảy ra? Câu trả lời là "có thể".
Trong C và C + +, ví dụ bạn phải khai báo một biến và kiểu của nó trước rồi bạn mới có thể sử dụng
nó Bây giờ bạn sẽ nhìn thấy lý do của việc đó. Trừ khi trình biên dịch biết kiểu của biến được lưu
trữ tại địa chỉ FFFFF0, nó không biết loại mã nó phải tạo ra để thao tác nó. Ngoài ra, nếu bạn muốn
lưu trữ một char tại FFFFF0, sau đó trình biên dịch có biết cần bao nhiêu không gian lưu trữ để phân
bổ vào nó.
Ngoài ra, thông báo rằng chúng tôi không thể truy cập địa chỉ 32-bit tại những địa chỉ khác với
những vùng được chia 4. Một số bộ xử lý sẽ cho phép chúng tôi để lưu trữ một giá trị 32-bit tại một
ranh giới kỳ lạ, như địa chỉ byte 000003-000006, nhưng phần lớn sẽ không cho. Lý do là bộ xử lý sẽ
phải làm thêm một số hoạt động để đọc toàn bộ giá trị bộ nhớ và sau đó làm một số công việc phụ để
tái tạo lại các byte vào đúng trình tự. Chúng tôi gọi đây là truy cập một nonaligned và nó thường khá
tốn kém về hiệu suất xử lý để cho phép nó xảy ra. Trong thực tế, nếu bạn nhìn vào bản đồ các tiến
trình lưu trữ và cấu trúc của bộ nhớ, bạn thường sẽ thấy không gian của vùng dữ liệu, tương ứng với
khoảng cách cố ý để không tạo ra các vùng dữ liệu chứa nonaligned truy cập.
Ngoài ra, nhận thấy rằng khi chúng tôi thực hiện truy cập từ 32-bit, bít địa chỉ a0 và a1 không sử
dụng. Điều này khiến chúng ta tự hỏi: “Nếu chúng ta không sử dụng chúng thì chúng có lợi ích gì?”.
Tuy nhiên chúng tôi cần chúng khi chúng tôi cần truy cập một byte đặc biệt từ 32-bit. A0 và A1
thường được gọi là dòng địa chỉ byte selector. Bởi vì đó là chứng năng chính của chúng. Điểm khác
biệt là chúng ta thật sự cần byte selecters khi chúng tôi đang viết vào bộ nhớ. Đọc từ bộ nhớ khá vô
hại, nhưng việc viết sẽ làm thay đổi mọi thứ. Do đó, bạn muốn chắc chắn rằng bạn sử đổi duy nhất
byte bạn quan tâm mà không phải là thứ khác. Từ quan điểm của nhà thiết kế phần cứng có byte
selecter cho phép bạn đủ điều kiện ghi thao tác một lần byte mà bạn quan tâm.
Nhiều bộ vi xử li sẽ không rõ ràng tại tất cả những dòng địa chỉ byte selecter . Thay vào đó, họ cung
cấp tình trạng bus trạng thái khi đủ điều kiện thao tác GHI vào bộ nhớ. Sẽ có điều gì khi lưu trữ vô
sô 16-bit (một kiểu dữ liệu ngắn) trong vùng bộ nhớ 32-bit? Cùng một quy tắc được áp dụng trong
trường hợp này. Chỉ có những địa chỉ hợp lệ sẽ là những địa chỉ chia hết cho 2, như là 000000,
000002, 000004,… Trong trường hợp địa chỉ 16-bit, thứ tự thấp nhất địa chỉ bit, A0, là không cần
thiết. Đối với bộ xử li 68K của chúng tôi, khi có bus dữ liệu rộng 16-bit đến bộ nhớ. Chúng tôi có
thể lưu trữ 2 byte trong mỗi từ của bộ nhớ. Do đó, A0 không được sử dụng cho các địa chỉ từ và trờ
thành byte selector cho bộ xử lí.

Hình 7.3 cho thấy bộ xử lí 32-bit điển
hình và giao diện bộ nhớ hệ thống. ĐỌC
tín hiểu từ bộ xử lí và tín hiệu CHIP
SELECT đã được bỏ qua cho rõ ràng.
Bộ xử lí có một bus dữ liệu 32-bit và
một bus địa chỉ 32-bit. Các chip bộ nhớ
đại diên cho tương ứng với một mặt của
RAM ở đâu đó trong không gian của bộ
xử lí.
Các mặt chính xác của bô nhớ sẽ được
xác định bằng việc thiết kế của người
giải mã địa chỉ khối logic. Các chip
RAM có khả năng của 1 Mbit và có
được 128K của 8.
Từ khi chúng tôi chó bus địa chỉ rộng
32-bit và mỗi chip RAM có 8 dòng dữ
liệu I/O, chúng tôi cần 4 chip bộ nhớ
trên bề rộng 128K. Chip #1 được nối
với dòng dữ liệu D0 qua D7 và chip #2
được được nối từ dòng dư liệu D8 qua
D15, chip #3 được nối từ dòng dữ liệu
D6 qua D23 và chip #4 được nối từ dòng dữ liệu D24 qua D31, và tương tự.
Các bus địa chỉ từ bộ xử lí có 30 dòng địa chỉ, có nghĩa là nó có khả năng của dài 2
30
từ (rộng 32-
bit). Bổ sung các bit địa chỉ cần thiết đến địa chỉ đầy đủ khoảng 2
32
byte được mặc định điều khiển
bởi bộ xử lí trong và điều khiển một cách rõ ràng qua tín hiệu 4 WRITE ENABLE có nhãn WE0
qua WE3.

Dòng địa chỉ A2 qua A18 từ bộ xủ lí được kết nối đến địa chỉ đầu vào A0 qua A16 của các chip
RAM, với A2 từ bộ xủ lí được nối tới A0 trên mỗi chip 4, và tương tự. Điều này có vẻ kỳ quặc lúc
đầu, nhưng nó sẽ làm bạn hiểu sau khi bạn nghĩ về nó. Thật ra, không có lý do đặc biệt mà mỗi
dòng địa chỉ từ bộ xử lí phải được nối với ống dữ liệu vào trên mỗi thiết bị nhớ. Cho ví dụ, A2 từ bộ
xử lí có thể được nối tới A14 của chip #1, A3 của chip #2, A8 của chip #3 và A16 của chip #4. Địa
chỉ cùng bộ xử lí sẽ giải quyết rõ ràng các địa chỉ byte khác nhau trong mỗi 4 bộ nhớ chip. Nhưng
miễn là tất cả 17 dòng địa chỉ từ bộ xử lí được nối với 17 dòng địa chỉ của các thiết bị nhớ, bộ nhớ
phải hoạt động đúng.
Trên các bit địa chỉ từ bộ xử lý, A19 qua A31 được sử dụng cho qua trình lựa chọn trang. Các tín
hiệu này được chuyển đến địa chỉ giải mã logic nơi mà các tín hiệu
CHIP SELECT
thích hợp được
tạo ra. Các tín hiệu này đã được bỏ qua từ hình 7.3. Có 13 cao mệnh lệnh địa chỉ bit trong ví dụ này.
Điều này cho chúng ta 213 hoặc 8,192 trang của bộ nhớ. Mỗi trang của bộ nhớ giữ 128K từ rộng 32-
bit, khi làm việc là 2
30
từ. Trong điều kiện của địa chỉ, mỗi trang thực sự chứa 512 Kbytes, vì thế
phạm vi byte địa chỉ trên mỗi trang đi từ địa chỉ byte (Trong HEX) 00000 qua 7FFFF. Nhớ lại rằng
trong sơ đồ bộ nhớ này, có 8192 trang với mỗi trang chứa 512 Kbytes. Vì vậy địa chỉ trang đi từ
0000 qua 1FFF. Nó không rõ ràng để bạn thấy được như thế nào để các trang địa chỉ và khoảng
chênh địa chỉ liên quan đến khoảng khác. Nhưng nếu bạn mở rộng các địa chỉ thập lục phân từ nhị
phân và đặt chúng bên cạnh khoảng khác bạn sẽ thấy đầy đủ 32-bit địa chỉ.
Bây giờ, chúng ta hãy xem cashc mà bộ xử lí xử lí với cỡ dữ liệu nhỏ hơn so với những từ dài. Giả
xử rằng bộ xử lí muốn đọc từ dài từ địa chỉ ABCDEF64 và địa chỉ này được giải mã để được trên
hình 7.3. Kể tử địa chỉ này trên giới hạn của 32-bit, A0 và A1 = 0, và không được sủ dụng như địa
chỉ ngoài mà đi vào bộ nhớ. Tuy nhiên, bộ xử lí muốn thực hiện truy cập từ của một trong những từ
tại địa chỉ ABCDEF64 hoặc ABCDEF66, nó sẽ còn tạo ra địa chỉ ngoài cùng. KHi dữ liệu được đọc
từ bộ xử lí, ½ những từ dài không cần thiết sẽ được loại bỏ. Do đây là thao tác đọc nên nội dung bộ
nhớ không bị ảnh hưởng.
Nếu bộ xử lí muốn đọc bất kì trong 4 byte đặt tại byte địa chỉ ABCDEF64, ABCDEF65,

ABCDEF66 hoặc ABCDEF67, nó sẽ vẫn thực hiện hoạt động đọc như trước. Một lần nữa chỉ có các
byte được quan tâm sẽ được giữ lại ngoài ra sẽ bị loại bỏ.
Bây giờ hãy xem lại hoạt động viết trong trường hợp này chúng tôi lo lắng có thể làm hỏng bộ nhớ,
do đó, chúng tôi muốn chắc chắn rằng khi chúng tôi ghi số lượng nhỏ hơn những từ dài vào bộ nhớ,
chúng tôi không ngẫu nhiên viết nhiều hơn chúng tôi dự kiến. Do đó, giả thuyết rằng chúng ta cần
ghi giá trị byte vào bộ nhớ ờ vị trí ABCDEF65. Trong trường hợp này, chỉ có tín hiệu WE1 sẽ được
khẳng định, do đó, chỉ có vị trí byte có thể được sửa đổi. Do đó, để ghi một byte vào bộ nhớ, chúng
tôi chỉ kích hoạt một trong 4 tín hiệu WRITE ENABLE. Để ghi một từ vào bộ nhớ chúng tôi sẽ kích
hoạt hoặc WE0 và WE1 với nhau hoặc WE2 và WE3. Cuối cùng, để ghi một từ dài, tất cả bốn của
dòng WRITE ENABLE sẽ được chỉ định.
Điều gì sẽ xảy ra về trường hợp của một từ 32-bit được lưu trữ trong một bộ nhớ 16-bit? Trong
trường hợp này, từ 32-bit có thể được lưu trữ trên bất kỳ từ ranh giới nào, bởi vì bộ xử lý luôn luôn
phải truy cập trên hai vùng bộ nhớ liên tiếp nhau để lấy đủ số lượng 32-bit. Tuy nhiên, hầu hết các
trình biên dịch vẫn sẽ cố gắng để lưu trữ từ 32-bit trên ranh giới tự nhiên (địa chỉ chia hết cho 4).
Đây là lý do tại sao lập trình viên assembly thường có thể tiết kiệm một không gian nhỏ hoặc tối ưu
tốc độ một thuật toán để vượt qua những gì mà trình biên dịch không để tạo ra mã và tinh chỉnh nó
cho hiệu quả cao hơn.
Hãy quay lại vấn đề trước. Đối với một bộ xử lý 32-bit, các bit địa chỉ A2 A31 có thể được sử
dụng để giải quyết 1,073,741,824 từ dài, và địa chỉ A0 A1 trong bốn byte có thể trong vòng từ dài.
Điều này cho chúng ta một tổng số là 4,294,967,296 byte địa chỉ địa điểm trong một bộ xử lý 32-bit.
Nói cách khác, chúng ta có một không gian địa chỉ byte của 4 GB. Một bộ xử lý với độ rộng bus 16-
bit, chẳng hạn như 68k, sử dụng dòng địa chỉ A1-A23 cho địa chỉ và A0 byte lựa chọn.
Kết hợp tất cả các điều này, bạn sẽ thấy được vấn đề. Bạn có thể có một byte 8-bit, một từ 16-bit
hoặc một từ 32-bit với địa chỉ tương tự. Điều này có phải là mơ hồ không? Có. Khi chúng ta đang
lập trình bằng một ngôn ngữ cấp cao, chúng ta phụ thuộc vào trình biên dịch để theo dõi những chi
tiết lộn xộn. Đây là một trong lý do tại sao khi thiết lập rập khuôn một loại biến khác có thể rất nguy
hiểm. Khi chúng tôi đang lập trình bằng một ngôn ngữ cấp thấp, chúng tôi phụ thuộc vào kỹ năng
lập trình theo dõi này.
Có vẻ dễ dàng đầy đủ, nhưng nó không phải. Điều này ít thực tế của cuộc sống máy tính là một trong
những nguyên nhân chính của lỗi phần mềm. Làm thế nào một khái niệm đơn giản có thể rất phức

tạp? Nó không phải phức tạp, nó chỉ là mơ hồ. Hình minh họa 7.4 cho vấn đề này. Các cột tận cùng
bên trái của hình 7.4 cho thấy một chuỗi được lưu giữ trong một không gian bộ nhớ 8-bit. Mỗi ký tự
ASCII chiếm vị trí nhớ kế tiếp.
Hình 7.4: Hai phương pháp đóng gói byte vào từ bộ nhớ 16-bit. Đặt thứ tự byte thấp vào cuối của từ
bậc thấp được gọi là Little Endian. Đặt thứ tự byte thấp ở bên tự cao của từ này được gọi là Big
Endian.
Cột giữa hiển thị một bộ nhớ 16-bit được tổ chức để bytes kế tiếp được lưu trữ từ phải sang trái. Các
byte tương ứng với A0 = 0 là liên kết với các phần thứ tự thấp, DB0. . . DB7, của từ 16-bit và byte
tương ứng để A0 = 1 là liên kết với phần tự cao, DB8 DB15, của từ 16-bit. Đây được gọi là tổ
chức Little Endian. Các cột bìa phải lưu trữ các ký tự như bytes kế tiếp từ trái sang bên phải. Các vị
trí byte tương ứng với A0 = 0 là liên kết với vị trí cao của từ 16-bit. Đây được gọi là tổ chức Big
Endian. Như một bài thực hành, xem xét cách các byte được lưu trữ trong hình 7.2. Có phải chúng
lớn hay Little Endian?
Motorola và Intel, đã chọn để sử dụng các công ước đầu cuối khác nhau và Pandora's Box đã được
mở cửa thế giới lập trình. Vì vậy, C hoặc mã C + + được viết cho một công ước có lỗi tinh tế khi
chuyển đến các công ước khác. Nó sẽ tồi tệ hơn đó. Các kỹ sư làm việc cùng nhau trên các dự án
giải thích sai số kỹ thuật nếu mục đích là một trong những quy ước và họ giả định khác. Các kiến
trúc ARM cho phép lập trình để thiết lập loại hình "endianess" sẽ được sử dụng bởi bộ vi xử lý lúc
mở điện. Vì vậy, trong khi bộ xử lý ARM có thể đối phó với một trong hai về cuối lớn hay nhỏ, nó
có thể không tự động chuyển chế độ một lần endianess. Hình 7,5 cho thấy sự khác biệt giữa hai công
ước cho một từ 32-bit đóng gói với bốn byte.
Nếu bạn lấy đi bất cứ điều gì
từ văn bản này, hãy nhớ vấn
đề này bởi vì bạn sẽ nhìn thấy nó ít nhất một lần trong sự nghiệp của bạn như là một nhà phát triển
phần mềm.
Trước khi bạn buộc tội tôi khi đánh chết chủ đề này, chúng ta hãy nhìn vào nó một lần nữa từ quan
điểm phần cứng. Toàn bộ khu vực của địa chỉ bộ nhớ có thể rất khó hiểu cho người mới lập trình
cũng như các cựu chiến binh dày dạn. Ngoài ra, có thể có sự giới thiệu mơ hồ của kiến trúc và thuật
ngữ của nhà sản xuất. Vì vậy, chúng ta hãy xem làm thế nào Motorola xử lý nó cho 68k và có lẽ điều
này sẽ giúp chúng ta hiểu rõ hơn về những gì thực sự đang diễn ra, ít nhất là trong trường hợp của bộ

xử lý Motorola, mặc dù chúng tôi đã xem xét vấn đề một lần trước trong hình 7.3 . Hình 7.6 tóm tắt
đề án giải quyết vấn đề bộ nhớ cho các bộ xử lý 68k.
Bộ xử lý 68k có khả năng trực tiếp giải quyết 16 MB bộ nhớ, đòi hỏi 24 "hiệu quả" dòng địa chỉ. Tại
sao? Bởi vì 224 = 16,777,216. Trong hình 7.6 chúng ta thấy 23 dòng địa chỉ. Dòng địa chỉ mất tích,
A0, được tổng hợp bởi hai tín hiệu điều khiển bổ sung, LDS và UDS.
Đối với một độ rộng bus 16-bit dữ liệu bên ngoài, chúng tôi bình thường dùng địa chỉ bit A0 làm bộ
chọn byte. Khi A0 là 0, chúng tôi chọn ngay cả byte, và khi A0 = 1, chúng tôi chọn byte lẻ. Các
endianness của 68k là Big Endian, để các byte thậm chí là liên kết với D8 qua D15 của bus dữ liệu.
Căn cứ theo con số 4.3.1 chúng ta thấy rằng có hai tình trạng tín hiệu bus ra khỏi bộ xử lý, UDS chỉ
định, hoặc Upper Data Strobe, và LDS, hoặc Lower Data Strobe.
Khi bộ vi xử lý là làm một byte truy cập vào bộ nhớ, sau đó hoặc là LDS hay UDS là khẳng định để
chỉ vào bộ nhớ mà một phần của từ đang được truy cập. Nếu thậm chí byte tại địa chỉ bị truy cập (A0
= 0), sau đó UDS khẳng định và LDS vẫn CAO. Nếu byte lẻ này đang được truy cập (A0 = 1), sau
đó LDS khẳng định và vẫn còn trong UDS CAO, hoặc OFF. Đối với một từ truy cập, cả hai UDS và
LDS được khẳng định. Hành vi này được tóm tắt trong bảng của hình 7,6.
Bạn thường sử dụng LDS và UDS như gating tín hiệu cho hệ thống điều khiển bộ nhớ. Ví dụ, bạn có
thể các mạch thể hiện trong hình 7.7 để kiểm soát đó của byte đang được ghi vào.
Bạn có thể bạn phải suy nghĩ về mạch này. Tại sao chúng ta sử dụng cổng OR? Chúng tôi có thể trả
lời câu hỏi theo hai cách. Trước tiên, kể từ khi tất cả các tín hiệu được khẳng định LOW, chúng tôi
đang thực sự đối phó với các tương đương logic tiêu cực của một chức năng AND. Cổng điều đó xảy
ra là tương đương logic tiêu cực của các cửa khẩu và là cửa ngõ OR, kể từ khi đầu ra là 0 nếu và chỉ
nếu cả hai đầu vào là 0. Cách thứ hai xem xét nó là thông qua các phương trình tương đương của các
định lý của DeMorgan.
Nhớ lại rằng:
Trong trường hợp này, phương trình 1 cho thấy OR của A và B
sẽ tương đương với bằng cách sử dụng A và B dương tính logic
và sau đó được cấp NAND của hai tín hiệu.
Bây giờ, giả sử rằng bạn đã cố gắng để làm một lúc truy cập từ một địa chỉ lẻ. Ví dụ, giả sử rằng bạn
đã viết các hướng dẫn lắp ráp ngôn ngữ sau đây:
Hướng dẫn này nói về cách các bộ xử

lý tạo ra 1 bản sao được đăng ký được
lưu giữ trong nội bộ của D0 và lưu trữ
các bản sao của từ đó trong bộ nhớ bên
ngoài, bắt đầu từ bộ nhớ địa chỉ $1.001.
Bộ xử lý sẽ cần phải thực hiện hai chu
kỳ bộ nhớ để hoàn tất việc truy cập bởi
vì thứ tự byte yêu cầu nó là cầu nối
chính xác của 2 điểm bộ nhớ byte. Một
số bộ xử lý có khả năng loại truy cập,
nhưng 68k là một trong những bộ vi xử
lý có thể không. Nếu một truy cập
không liên kết xảy ra, bộ vi xử lý sẽ tạo
ra một ngoại lệ và cố gắng cảnh báo
một số mã người dùng xác định rằng sẽ
sửa lỗi, hoặc ít nhất, không chết cứng.
Kể từ khi bộ xử lý 68k là một bộ xử lý
trong rộng 32-bit, nhưng với độ rộng bus dữ liệu 16-bit của bộ nhớ ngoài, chúng ta cần phải biết làm
thế nào nó lưu lượng 32-bit trong bộ nhớ bên ngoài là tốt. Hình 7.8 chỉ cho chúng ta quy ước để lưu
trữ từ lâu trong bộ nhớ.
Mặc dù hình 7.8 có thể có vẻ khó hiểu, nó chỉ là một tuyên bố rõ ràng hơn của hình 7.2 trong một
định dạng khá hơn phần nào viết tắt. Con số này cho chúng ta biết rằng dữ liệu 32-bit, được gọi là
chờ đợi hay từ lâu được lưu trữ trong bộ nhớ với ý nghĩa nhất 16 bit (D16 - D31) được lưu giữ trong
vị trí địa chỉ đầu tiên từ và ít nhất 16 bit (D0 - D15) được lưu giữ ở vị trí cao nhất từ kế tiếp. Ngoài
ra, ngay cả các địa chỉ byte được liên kết với phần tử cao của địa chỉ từ 16-bit (Big Endian).
Giới thiệu về ngôn ngữ assembly
Các máy tính trên thế giới bị chi phối bởi một kiến trúc tập lệnh (ISA) đầu tiên được xác định bởi
Intel hơn 25 năm trước đây. Kiến trúc này, được gọi là X86 bởi vì chúng cùng một dòng, các thế hệ
sau:
8080 →8086 →80186 →80286 →80386 →80486 →Pentium
Thế giới của nhúng bộ vi xử lý - đó là bộ vi xử lý được dùng để mục đích duy nhất bên trong thiết

bị, như điện thoại di động - bị chi phối bởi Motorola 680 X0 ISA:
68000 →68010 →68020 →68030 →68040 →68060 →ColdFire
ColdFire đơn vị kiến trúc vi xử lý hiện đại, được gọi là RISC, với tính tương thích ngược với kiến
trúc gốc 68K ISA. (Chúng tôi sẽ nghiên cứu các kiến trúc trong một bài học sau này.) Tính tương
thích ngược rất quan trọng vì mã 68K vẫn đang được sử dụng và phát triển. Tập lệnh Motorola 68K
là một trong những ISAs nghiên cứu rộng rãi nhất và bạn có thể tìm thấy một số không thể tin nổi
của kết quả nếu bạn làm tìm kiếm web trên " 68K " hoặc " 68000. "
Mỗi hệ thống máy tính đều có hoạt động cơ bản mà nó có thể thực hiện. Các hoạt động này được xác
định bởi tập lệnh của bộ vi xử lí. Lý do của tập hợp các hướng dẫn đó là cách làm việc của máy tính
được tổ chức trong nội bộ và được thiết kế hoạt động. Đây là những gì chúng tôi sẽ dung để gọi cho
kiến trúc của máy tính. kiến trúc này được phản ánh bởi các hướng dẫn bằng ngôn ngữ assembly mà
nó có thể thực hiện, bởi vì các hướng dẫn này là các kỹ thuật mà chúng tôi truy cập tài nguyên của
máy tính. Các tập lệnh là yếu tố nguyên tử của các bộ xử lý. Tất cả các thao tác phức tạp trên được
thực hiện bằng cách xây dựng những dãy các thao tác cơ bản.
Máy tính không đọc ngôn ngữ assembly. Chúng lấy lệnh của chúng trong mã máy. Như bạn biết đó,
mã máy được thiết đặt vào bảng vi điều khiển mã máy khi bắt đầu quá trình thực thi lệnh. Ngôn ngữ
assembly là con người có thể đọc được các dạng lệnh của ngôn ngữ máy. Không có gì huyền bí về
lệnh của ngôn ngữ máy, và rất nhanh chóng bạn sẽ có thể hiểu chúng và thấy các mẫu hướng dẫn
trạng thái bên trong máy móc của bộ vi xử lí hiện đại. Bây giờ chúng ta sẽ tập trung vào việc ngôn
ngữ assembly. Xem hình 7.9.
Lưu ý: chúng tôi đại diện cho số hệ thập lục phân trong C hoặc C + + với tiền tố '0x' Đây là tiêu
chuẩn hóa của ngôn ngữ. Không có tiêu chuẩn hóa ứng với ngôn ngữ assembly và khác nhà
phát triển trình dịch assembly biểu diễn hệ số thập lục phân bằng nhiều cách khác nhau. Trong
văn bản này, chúng ta sẽ áp dụng quy ước Motorola của dùng tiền tố ‘S' cho hệ thập lục phân.
Ngôn ngữ mã máy tính thực sự là đầu ra của trình biên dịch hợp ngữ chuyển đổi tập tin nguồn của
ngôn ngữ assembly, bạn có thể soạn với bất kỳ trình soạn thảo văn bản, mã ngôn ngữ máy tương ứng
có thể được thi hành bởi bộ xử lý 680x0. Bên tay trái hộp thực sự có hai cột, mặc dù có thể khó thấy
chúng. Cột bên trái bắt đầu với vị trí bộ nhớ hệ thập lục phân nơi lệnh ngôn ngữ máy được lưu trữ.
Trong trường hợp này bộ nhớ vị trí $00000412 giữ lệnh ngôn ngữ máy mã 0x307B7048. Lệnh kế
tiếp bắt đầu vào bộ nhớ vị trí 0x00000416 và chứa mã lệnh 0x327B704A. Hai lệnh ngôn ngữ máy

được trao cho bằng lệnh assembly này.
MOVEA.W (TEST_S,PC,D7),A0
MOVEA.W (TEST_E,PC,D7),A1
Chẳng bao lâu bạn sẽ thấy những lệnh này thật sự có nghĩa là gì. Bây giờ chúng ta có thể tóm tắt ở
trên theo cách thảo luận này:
• Bắt đầu ở bộ nhớ vị trí $00000412, và chạy qua vị trí $00000415, là lệnh máy mã
B7048$307. Lệnh assembly tương ứng dữ liệu ngôn ngữ máy này là MOVEA.W
(TEST_S,PC,D7),A0
• Bắt đầu ở ở bộ nhớ vị trí $00000416, và chạy qua vị trí $00000419, là lệnh máy mã
$327B704A. Lệnh assembly tương ứng dữ liệu ngôn ngữ máy này là MOVEA.W
(TEST_E,PC,D7),A1
Hơn nữa, cho tập lệnh 68 K, lệnh ngôn ngữ máy tính nhỏ nhất có độ rộng bit là 16 ( 4 chữ số thập
lục phân). Không lệnh nào được nhỏ hơn 16-bit, mặc dù một số lệnh có thể là khi dài khi 5, 16-bit
từ.
Có 1:1 tương ứng giữa các lệnh
của ngôn ngữa assembly và các
lệnh của ngôn ngữ máy. Các lệnh
của ngôn ngữ assembly được gọi
là thuật nhớ. Chúng được thiết kế
để ghi nhớ tốc ký như lệnh thực
tế. Cho ví dụ:
Bạn sẽ nhận thấy rằng tôi đã chọn
một phông chữ khác nhau cho các lệnh ngôn ngữ assembly. Đây là bởi vì kiểu chữ với định khoảng
cách cố định, như " người đưa tin ", kí tự trong cột tuân thủ theo việc canh chỉnh, làm nó dễ đọc hơn
lệnh của ngôn ngữ assembly. Không có quy định nào bạn phải sử dụng kiểu chữ này, assembly có lẽ
không quan tâm, nhưng nó có thể làm cho bạn dễ dàng hơn đọc và hiểu chương trình của bạn nếu
bạn làm.
Một phần của lệnh cho máy tính biết phải làm gì, được gọi là opcode ( viết tắt cho " thao tác mã " ).
Đây chỉ là một nửa lệnh. Một nửa khác cho máy tính như thế nào và đâu thao tác này nên thực hiện.
Các opcode thục tế, ví dụ MOVE.B, là opcode thực tế và từ bổ nghĩa. Opcode là MOVE. Nó nói

rằng một số dữ liệu nên được chuyển từ một nơi khác. Từ bổ nghĩa là hậu tố ". B ". Điều này nói nó
MOVE.B move a byte of data
MOVEA.W move a word of data to an address register
CMP.B compare the magnitude of two bytes of data
BEQ branch to a different instruction if the result
equals zero
BEQ add (quickly) two values
BRA always branch to a new location
chuyển byte dữ liệu, thay vì từ nhớ hoặc từ nhớ dài. Để hoàn chỉnh lệnh chúng ta phải ra lệnh cho bộ
xử lý :
1. Nơi để tìm ra dữ liệu ( đây là được gọi là toán hạng 1 ), và
2. Nơi đặt kết quả ( toán hạng 2 ).
Để hoàn chỉnh lệnh ngôn ngữ assembly phải có opcode và có thể có 0,1 hoặc 2 toán hạng.
Đây là những lệnh assembly đầu tiên của bạn. Nó được gọi là NOP ( phát âm là No op ). Nghĩa là
chẳng làm gì. Bạn có thể là chất vấn tính đúng đắn của lệnh này nhưng nó là thực sự hoàn toàn hữu
ích. Trình biên dịch làm rất tốt khi sử dụng chúng. Lệnh NOP là ví dụ của lệnh lấy 0 toán hạng.
Lệnh CLR.L D4 là ví dụ của lệnh lấy một toán hạng. Nghĩa là để rõ, hoặc ấn định thành không, cả
32 bit ( " . L " từ bổ nghĩa ) của thanh ghi bên trong, D4.
Lệnh MOVE.W D0, D3 là ví dụ của lệnh lấy hai toán hạng. Chú thích dấu phẩy riêng biệt hai toán
hạng, D0 và D3. Lệnh bảo bộ xử lý di chuyển 16 bit của dữ liệu ( " . W " modifer ) từ dữ liệu thanh
ghi D0 để D3 thanh ghi dữ liệu. Nội dung của D0 đều không thay đổi bởi thao tác. Tất cả chương
trình hợp ngữ tuân theo cấu trúc sau :
Column 1 Column 2 Column 3 Column 4 . . . .
LABEL OPCODE OPERAND1,OPERA
ND2
*COMMENT
Mỗi lệnh chiếm đóng một dòng văn bản, bắt đầu ở cột 1 và sẽ lên tới 132 cột.
1. Trường LABEL là tùy chọn, nhưng nó luôn phải bắt đầu trong cột đầu tiên của dòng. Chúng
tôi sẽsớm xem cách sử dụng nhãn.
2. OPCODE là kế tiếp, Nó phải tách biệt với LABEL bằng khoảng trắng, như là một tab, kí tự

hay vài dấu cách, và nó phải bắt đầu ở cột 2 hoặc sau đó.
3. Sau đó, OPERAND (toán hạng) tách biệt với OPCODE bằng khoảng trắng, thường kí tự tab.
Hai toán hạng nên tách biệt với nhau bằng dấu phẩy. Không có trắng khoảng cách giữa toán
hạng và dấu phẩy.
4. COMMENT là trường cuối cùng của dòng. Thường bắt đầu với dấu hoa thị hoặc dấu chấm
phẩy, phụ thuộc nhờ đó trình dịch hợp ngữ đang được sử dụng. Bạn có thể còn có chú thích
tuyến, nhưng sau đó dấu hoa thị phải ở cột 1.
Label
Mặc dù label là tùy chọn, nó là bộ phận quan trọng của việc lập trình bằng assembly. Bạn đã biết
làm thế nào để sử dụng label khi bạn gán nó cho biến hay hằng số. Bạn cũng dùng label để đặt tên
chức năng. Ở assembly chúng tôi thường dùng label để tham khảo để địa chỉ bộ nhớ phù hợp với
lệnh hay dữ liệu trong chương
trình. Label phải định nghĩa ở
cột 1 của chương trình của bạn.
Label làm cho chương trình dễ
đọc hơn. Có thể ghi chương
trình không có sử dụng Label,
nhưng thực ra chẳng ai bao giờ
làm huyện đó như thế. Label
cho phép trình dịch hợp ngữ
chương trình để tự động ( và
chính xác ! ) tính địa chỉ của toán hạng và
đích. Chẳng hạn như, xem xét đoạn mã rút trích sau trong hình 7.10
Mã trong ví dụ hình 7.10 có hai Label, TEST_LOOP and DONE. Label này tương ứng để vị trí bộ
nhớ của lệnh, " MOVE.B ( A2 ), D6 " và " BRA TEST_LOOP " tương ứng. Khi trình dịch hợp ngữ
thực hiện tiến trình chuyển đổi lệnh assembly vào lệnh ngôn ngữ máy nó theo dõi mỗi lệnh ở bên
trong bộ nhớ. Khi nào
nó gặp label với tư cách một toán hạng, nó thay thế văn bản label với giá trị số. Vì vậy, lệnh " BEQ
DONE " bảo trình dịch assembly tính giá trị số cần thiết để gây ra chương trình để nhảy đến lệnh tại
vị trí bộ nhớ phù hợp với label " DONE " nếu thử nghiệm điều kiện, bình đẳng, được đáp ứng.

Chúng ta sẽ sớm xem cách thử nghiệm bình đẳng này. Nếu thử nghiệm thất bại, lệnh rẽ nhánh bị
phớt lờ và lệnh kế tiếp được thi hành.
Comments
Trước khi chúng tôi đi quá xa, chúng tôi cần phải đóng góp một vài ý kiến về hình thức thích hợp
cho việc ghi chú trong chương trình của bạn. Như bạn thấy trong hình 7,10 mỗi comments có một
bình luận liên quan với nó. Những trình biên dịch khác nhau sẽ có những cách comment khác nhau.
Một số ý kiến yêu cầu comment trên một dòng với ký tự đầu dòng là “*” hoặc “,”. Comment có liên
quan hướng dẫn hoặc chỉ thị có thể cần các dấu chấm phẩy hoặc dấu hoa thị để bắt đầu comment,
hoặc họ có thể không cần bất kỳ ký tự đặc biệt bởi vì các khoảng trắng trước đó xác định vị trí của
khối comment. Điểm quan trọng là mã thực thi assemly không tự ghi dẩn chứng, và bạn dễ dàng
quên nó, hoặc lảng quên nó sau một ngày, đó là cách ghi chú chính xác những gì bạn đã cố gắng để
làm với các thuật toán đó.
Mã assembly nên có nhiều comment. Không chỉ giúp bạn nhớ rành mạch, mà còn giúp những người
sẽ phải phát triển mã của bạn sau khi bạn di chuyển sang công việc khác. Không có lý do rằng mã
assembly không thể dễ đọc cũng như một tài liệu như C++ . Việc sử dụng comment tương đương với
việc loại bỏ số bí ẩn và để giúp giải thích rõ những gì đoạn mã đang làm. Sử dụng các khối comment
cho những gì các phần của một thuật toán đang làm và những gì các giả định đang được thực hiện.
Cuối cùng comment như một nhóm nhỏ các hướng dẫn, để làm cho nó hoàn toàn rõ ràng những gì
đang xảy ra.
Trong cuốn sách của mình, hacker: Anh hùng của cuộc Cách mạng máy tính, Steven Levy
1
mô tả các
kiểu mã hóa của Peter Samson, một sinh viên MIT, và lập trình sớm,
…Samson, cho dù, là đặc biệt tối nghĩa trong không chịu thêm chú thích cho nguồn của mã anh ấy,
giải thích những gì anh ấy đang làm việc tại thời gian đã cho. Một chương trình tốt – dược phân
phối Samson ghi tiếp tục cho vài hàng trăm lệnh assembly, chỉ với một bình luận bên cạnh đó có
một chỉ thị số 1750. Chú thích là RIPJSB,Và mọi người vắt óc suy nghĩ về nghĩa của nó cho đến ai
đó hình dung ra 1750 là Năm Bach chết, và Samson đã viết ra cho an nghỉ của Rest In Peace
Johann Sebastian johann.
Mẫu kiến trúc của lập trình viên

Để chương trình trong hợp ngữ, chúng tôi phải biết rõ kiến trúc cơ bản của bộ xử lý. Cái nhìn của
chúng tôi về kiến trúc được gọi là mẫu của lập trình viên của bộ xử lý. Chúng tôi phải hiểu hai khía
cạnh kiến trúc :
1. tập lệnh, và
2. kiểu địa chỉ
Kiểu địa chỉ của máy tính mô tả cách khác nhau trong đó nó truy cập toán hạng,
hay truy lục dữ liệu cho hoạt động trên. Sau đó, kiểu địa chỉ mô tả những gì phải làm với dữ liệu
đằng sau thao tác hoàn tất. Kiểu địa chỉ cũng nói với bộ xử lý cách tính đích của tìm về lệnh
nonsequential, như là một nhánh hoặc nhảy đến vị trí mới.
Kiểu địa chỉ là rất quan trọng để hiểu biết về máy tính chúng tôi sẽ cần nghiên cứu chúng một chút
trước khi chúng tôi có thể tạo ra chương trình assembly. Vì vậy, không giống C, C + + hay Java,
chúng tôi sẽ cần phát triển mức nhất định của hiểu biết cho máy chúng ta đang lập trình trước khi
chúng ta có thể thực sự ghi chương trình.
Không giống C hoặc C + +, hợp ngữ không phải là cơ động được giữa máy tính. Chương trình hợp
ngữ ghi cho Intel 80486 sẽ không chạy trên Motorola 68000. Chương trình C viết cho chạy trên Intel
80486 có thể chạy trên Motorola 68000 một lần mã nguồn gốc được biên dịch lại cho tập lệnh
68000, nhưng sự khác biệt trong kiến trúc, như là lớn và nhỏ endian, có thể làm lỗi được giới thiệu.
Nó có thể là đáng giá và dừng lại một lúc để phản ánh về lý do tại sao, như là một lập trình viên,
điều quan trọng để tìm hiểu assembly. Khoa học máy tính và lập trình phụ thuộc vào kiến thức làm
việc của bộ vi xử lý, hạn chế của nó và thế mạnh của nó. Để biết được assembly hiểu được những
động cơ tính toán rằng mã của bạn đang chạy. Mặc dù ngôn ngữ cấp cao giống như C + + và JAVA
làm tốt công việc của chi tiết abstracting mức độ thấp, điều quan trọng là để giữ nhớ rằng động cơ
không phải là vô hạn mạnh mẽ và tài nguyên của nó không phải là vô hạn.
Ngôn ngữ assembly là chặt chẽ cùng với việc thiết kế các bộ vi xử lý và đại diện cho mức độ đầu
tiên của đơn giản hóa các hướng dẫn thiết lập kiến trúc nhị phân thành dạng có thể đọc được con
người. Nói chung
có 1:1 trùng khớp giữa lệnh assembly và nhị phân hoặc lệnh hệ thập lục phân kết quả. Điều này là
rất khác với C hay C + +, C, nơi một C câu lệnh, có thể tạo ra hàng trăm dòng mã lắp ráp.
Nó vẫn còn đúng mà bạn có thể thường ghi mã chặt trong assembly. Trong khi trình biên dịch C đã
đạt khá tốt, chúng không là hoàn hảo. Chương trình viết assembly sẽ thường sử dụng kém hơn dấu

cách và chạy nhanh hơn chương trình với cùng tính năng viết trong C. Một số trò chơi vẫn còn mã
trong hợp ngữ cho lý do chính xác.
Nhu cầu cần có mã hiệu quả đặc biệt đúng của bộ điều khiển ngắt và thuật toán ghi cho bộ xử lý
chuyên dụng, như là bộ xử lý tín hiệu kỹ thuật số ( dsps ). Nhiều lập trình viên kinh nghiệm sẽ biện
luận rằng mọi mã phải được xác định hoàn toàn không thể được viết bằng C, bởi vì bạn không thể dự
đoán trước thời hạn thời gian thi hành cho mã được tạo ra bởi trình biên dịch. Với assembly bạn có
thể điều khiển chương trình của bạn ở mức của chu kỳ đồng hồ đơn. Hơn nữa, nhất định các bộ phận
của thời gian thi hành môi trường phải được viết bằng assembly vì bạn cần phải có thể mới thiết lập
thi hành môi trường C. Vì vậy, mã khởi động có xu hướng được viết bằng asembly. Cuối cùng, sự
biết hiểu assembly là cực kì quan trọng để khắc phục lỗi hệ thống thời gian thực. Nếu bạn có chương
trình đã bao giờ trong môi trường lập trình như là trực quan của Microsoft C+ + ® và trong khi bạn
đang khắc phục lỗi, bạn vô tình bước vào hàm thư viện, bạn sau đó sẽ tìm tự mình thấy sâu tận trong
x86 assembly.
Kiến trúc bộ vi xử lí Motorola 68000
Hình 7.11 là biểu đồ đơn giản hóa của kiến trúc 68 K. Từ khi motorola có số lượn lớn thành viên
trong dòng kiến trúc cụ thể là CPU16. CPU16 là tập hợp con của kiến trúc CPU32, ISA cho 68020
và bộ xử lý sau này.
Chúng ta hãy nhận dạng nhanh một vài khối thiết thực quan trọng mà chúng tôi sẽ sử dụng sau này.
• Bộ đếm chương trình: được dùng để giữ địa chỉ của lệnh kế tiếp được tìm nạp từ bộ nhớ.
Ngay khi lệnh hiện hành được giải mã bằng bộ xử lý chương trình truy cấp ( program counter
- PC) được cập nhật để chỉ đến địa chỉ của lệnh tuần tự kế tiếp trong bộ nhớ.
• Thanh ghi tổng quát : bộ xử lý 68 K có 15 thanh ghi đa năng và hai thanh ghi chuyên biệt.
Thanh ghi đa năng được chia thành thông tin đăng ký vào bộ nhớ thành tám gói dữ liệu,
D0 D7 và bảy địa chỉ A0 A6. Dữ liệu thanh ghi được sử dụng để giữ và xử lý dữ liệu biến
và thanh ghi địa chỉ được dùng để giữ và chế biến địa chỉ bộ nhớ. Hai mục đích đặc biệt của
thanh ghi là được dùng bổ sung cho 2 ngăn xếp con trỏ, A7 và A7 '. Chúng ta sẽ thảo luận về
ngăn xếp phía sau trong văn bản này.
• Tình trạng thanh ghi : tình trạng thanh ghi là thanh ghi 16 bit. Bit được dùng để mô tả trạng
thái hiện hành của máy tính trên lệnh theo lệnh cơ sở. Mã điều kiện thanh ghi, CCR, là một
phần của tình trạng thanh ghi và giữ bit trực tiếp liên quan đến kết quả của cuối cùng lệnh

thực thi.
• Đơn vị lôgic và số học ( ALU) : ALU là khối thiết thực nơi mọi toán học và thao tác dữ liệu
logic được thực hiện.
Hình 7.12 là mẫu kiến trúc 68
K của lập trình viên Nó khác
với hình 7.11 bởi vì nó chỉ có
tập trung vào chi tiết của kiến
trúc đó là liên quan đến ghi
chương trình.
Trong văn bản này, chúng tôi
không là đi để xử lý tình trạng
thanh ghi ( SR ), hoặc giám sát
viên ngăn xếp con trỏ ( A7').
Từ giờ trở đi chúng tôi sẽ tập
trung vào D0. D7, A0. A6, A7,
CCR và PC. Từ thanh ghi này,
chúng tôi sẽ học mọi thứ khi đó
chúng tôi cần biết về kiến trúc máy tính này và ngôn ngữ assembly
Qui tắc của thanh ghi điều kiện
Qui tắc của thanh ghi điều kiện (CCR) cần
một số giải thích thêm. Thanh ghi sẽ thể hiện
cụ thể hơn trong hình 7.13.
CCR là một tập có chứa năm bit điều kiện có giá trị có thể thay đổi với kết quả của hướng dẫn từng
được thực hiện. Định nghĩa chính xác của mỗi bit được tóm tắt dưới đây.
• X BIT (bit mở rộng): được sử dụng với đa số học chính xác
• N BIT (bit tiêu cực): chỉ ra rằng kết quả là một số âm
• Z BIT (bit không): chỉ ra rằng kết quả là bằng không
• V BIT (overflow): chỉ ra rằng kết quả có thể đã vượt quá phạm vi của các toán hạng
• C BIT (bit mang theo): chỉ ra rằng một thực được tạo ra trong một hoạt động toán học
Tầm quan trọng của các bit cư trú này với dòng kiểm thử và lệnh rẽ nhánh như BEQ, BNE, BPL,

BMI, v.v Những chỉ dẫn này kiểm tra các điều kiện của một cờ riêng biệt, hoặc bit CCR, và cả hai
có điều kiện rẽ nhánh là đúng, hoặc bỏ qua các rẽ nhánh và đi đến các chỉ lệnh kế tiếp nếu điều kiện
là sai. Ví dụ, BEQ có nghĩa là nhánh bằng nhau. Vâng, bằng những gì? Các hướng dẫn BEQ thực sự
là thử nghiệm cho tổ chức của các cờ không, Z. Nếu Z = 1, có nghĩa là các kết quả đăng ký là số
không, do đó, chúng ta nên dùng các điều kiện rẽ nhánh vì kết quả là bằng không. Vì vậy, các nhánh
ngang hàng là một hướng dẫn mà cho bộ xử lý để có rẽ nhánh nếu có một hoạt động gần đây dẫn đến
một kết quả bằng không.
Nhưng BEQ có nghĩa là cái gì khác. Giả sử chúng ta muốn biết nếu hai biến đều bằng với nhau. Làm
thế nào chúng ta có thể kiểm tra điều đó? Đơn giản, chỉ cần trừ đi một trong những từ khác. Nếu
chúng ta có được một kết quả zero (Z = 1), thì chúng đang bằng nhau. Nếu chúng không bằng với
nhau, chúng tôi sẽ có được một kết quả khác không và (Z = 0). Như vậy, BEQ là đúng nếu = Z 1 và
BNE (nhánh không bằng) là đúng nếu Z = 0. BPL (nhánh cộng thêm) là đúng nếu = N 0 và BMI (trừ
nhánh) là đúng nếu (N = 1).
Có tổng số 14 nhánh có điều kiện trong những hướng dẫn 68k. Một số thử nghiệm chỉ có các điều
kiện của một cờ duy nhất, những người khác thử nghiệm các kết hợp hợp lý của cờ. Ví dụ, hướng
dẫn BLT (rẽ nhánh ít hơn) được xác định bởi: BLT = N * V + N * V (N ⊕V) (chứ không phải bởi
lợn xông khói, rau diếp, và cà chua).
Địa chỉ hiệu lực
Ghi chú: mặc dù bộ xử lý 68K chỉ có 24 hàng địa chỉ ngoài đối với bộ xử lý, nội tại đó còn là một bộ
xử lý 32- bít. Như vậy, chúng tôi có thể đại diện cho các địa chỉ như các giá trị 32 trong những ví
dụ (của) chúng tôi.
Bây giờ chúng ta hãy quay lại và nhìn vào định dạng của các hướng dẫn. Có lẽ sự hướng dẫn thông
dụng nhất là câu lệnh Move. Bạn sẽ thấy rằng hầu hết những gì bạn làm trong ngôn ngữ assemly là
chuyển dữ liệu xung quanh. Các câu lệnh Move có hai toán hạng. Nó trông như thế này:
MOVE.W source(EA),destination(EA)
Ví dụ:
MOVE.W $4000AA00,$10003000
cho các bộ xử lý để sao chép các giá trị 16-bit được lưu trữ trong bộ nhớ để 0x4000AA00 vị trí
0x10003000 vị trí bộ nhớ.
Đồng thời, Move gợi nhớ lệch lạc. Những gì các hướng dẫn không thể ghi đè nội dung của toán hạng

đích lên toán hạng nguồn. Toán hạng nguồn không thay đổi do hoạt động. Như vậy, sau khi hướng
dẫn cả hai địa chỉ bộ nhớ chứa dữ liệu giống như $ 4000AA00 đã làm trước khi chỉ thị đã được thực
thi.
Trong ví dụ trước, toán hạng nguồn và toán hạng đích là địa chỉ trong bộ nhớ được quy định chính
xác. Đây là những địa chỉ tuyệt đối. Chúng là tuyệt đối bởi vì hướng dẫn các quy định cụ thể chính
xác nơi để lấy dữ liệu từ và nơi để đặt nó. Địa chỉ tuyệt đối chỉ là một trong những địa chỉ có thể của
chế độ 68k. Chúng tôi kêu gọi các phương thức giải quyết hiệu quả các địa chỉ. Vì vậy, khi chúng tôi
viết dưới hình thức chung của chỉ thị:
MOVE.W source(EA),destination(EA)
chúng tôi đang nói rằng nguồn và nơi đến của dữ liệu để di chuyển sẽ độc lập được xác định bởi
cách đánh địa chỉ có hiệu quả cho mỗi chúng.
Ví dụ:
MOVE.W D0,$10003000
di chuyển nội dung của một trong tám thanh ghi dữ liệu nội bộ trong bộ xử lý, trong trường hợp dữ
liệu ở thanh ghi D0, đến vị trí bộ nhớ 10.003.000 $. Trong ví dụ này, địa chỉ nguồn có hiệu quả chế
độ được gọi là dữ liệu đăng ký trực tiếp và địa chỉ đích đến là phương thức hiệu quả tuyệt đối.
Chúng tôi có thể viết câu lệnh MOVE như sau:
MOVE.W A0,D5
mà sẽ di chuyển từ 16-bit, hiện được lưu giữ trong thanh ghi địa chỉ A0 đến thanh ghi dữ liệu D5.
Hiệu quả nguồn địa chỉ là thanh ghi địa chỉ đăng trực tiếp và đích đến địa chỉ có hiệu quả là thanh
ghi dữ liệu trực tiếp.
Giả sử rằng nội dung của thanh ghi địa chỉ A0 là $ 4000AA00 (chúng tôi có thể viết điều này trong
một ký hiệu viết tắt là = $ 4000AA00). Câu lệnh như sau
MOVE.W D5,(A0)
di chuyển nội dung của thanh ghi dữ liệu cho vị trí bộ nhớ D5 4000AA00 $. Đây là một ví dụ về địa
chỉ của thanh ghi địa chỉ gián tiếp. Có lẽ bạn đã quen thuộc với chế độ giải quyết này vì đây là một
con trỏ trong C + +. Nội dung của địa chỉ đăng ký trở thành địa chỉ của các hoạt động bộ nhớ. Chúng
tôi gợi ý chế độ này một địa chỉ gián tiếp vì nội dung thanh ghi địa chỉ không phải là dữ liệu chúng
ta muốn, mà là địa chỉ bộ nhớ của dữ liệu chúng ta muốn. Vì vậy, chúng tôi không lưu trữ dữ liệu
trực tiếp đến thanh ghi A0, nhưng gián tiếp bằng cách sử dụng các nội dung của A0 như một con trỏ

đến đích cuối cùng của nó, bộ nhớ vị trí $4000AA00. Chúng tôi chỉ ra rằng thanh ghi địa chỉ đang
được sử dụng như là một con trỏ vào bộ nhớ của các dấu ngoặc xung quanh thanh ghi địa chỉ. Giả sử
= $ 10003000 và = $ 4000AA00. Câu lệnh
MOVE.W (A1),(A6)
sẽ sao chép các dữ liệu nằm ở vị trí bộ nhớ $10003000 đến vị trí bộ nhớ $ 4000AA00. Cả hai địa chỉ
nguồn và đích đến chỉ các phương thức hiệu quả là những thanh ghi địa chỉ gián tiếp.
Hãy xem thêm 1 ví dụ
MOVE.W #$234A,D2
sẽ chuyển đổi sang hệ thập lục phân, $ 234A ghi trực tiếp vào thanh ghi D2. Đây là một ví dụ về các
chế độ địa chỉ cấp tốc. Ngay lập tức giải quyết vấn đề là cơ chế mà theo đó các biến bộ nhớ được
khởi động. Dấu thăng (#) cho biết các lập trình viên assemly biết rằng đây là một số, không phải là
một vị trí bộ nhớ. Tất nhiên, chỉ có hiệu quả địa chỉ nguồn có thể là một địa chỉ cấp tốc. Các điểm
đến không thể được một số nó phải là một vị trí bộ nhớ hoặc một thanh ghi.
Địa chỉ hiệu quả (EA) quy định cụ thể như thế nào toán hạng của lệnh sẽ được truy cập. Tùy theo sự
hướng dẫn đang được thực hiện, không phải tất cả các địa chỉ có hiệu quả có thể có sẵn để sử dụng.
Chúng tôi sẽ thảo luận nhiều hơn là chúng tôi đi. Loại địa chỉ hiệu quả mà sẽ được sử dụng bởi các
chỉ thị để truy cập vào một hoặc nhiều toán hạng là thực sự được quy định như một phần của chỉ thị.
Nhớ lại rằng kích thước tối thiểu cho một từ opcode là 16-bit chiều dài. Từ opcode cung cấp tất cả
các thông tin mà bộ xử lý những nhu cầu để thực hiện các hướng dẫn. Tuy nhiên, đó không có nghĩa
là từ của opcode 16-bit, bởi chính nó, có tất cả các thông tin trong hướng dẫn này. Nó có thể chứa đủ
thông tin để được hướng dẫn toàn bộ, giống như NOP, nhưng thông thường nó chỉ chứa đủ thông tin
để biết những gì khác thì phải lấy, hoặc lấy từ bộ nhớ để hoàn thành các chỉ dẫn. Vì vậy, nhiều
hướng dẫn có thể dài hơn phần từ opcode của chỉ thị.
Nếu chúng ta suy nghĩ về mã máy trên nền tảng vi xử lý ổ đĩa, tất cả điều này bắt đầu có ý nghĩa.
Chúng ta cần từ op-code để cung cấp cho chúng tôi điểm vào của chúng tôi vào các mã vi xử lý. Đây
là những gì các bộ xử lý không thể làm khi nó giải mã một lệnh. Trong quá trình thực hiện các
hướng dẫn toàn bộ, có thể cần phải đi ra bộ nhớ ngoài một lần nữa để lấy toán hạng bổ sung để hoàn
thành các chỉ dẫn. Nó biết rằng nó phải làm những bộ nhớ bổ sung vì đường dẫn thông qua nền tảng
máy, theo định nghĩa của từ op-code, thúc ép nó.
Hãy xem xét hình thức của từ opcode cho

các hướng dẫn Move thể hiện trong
hình 7.14
Trường op-mã có thể chứa ba loại
thông tin về các hướng dẫn di chuyển trong lĩnh vực được xác định bởi bốn bit dữ liệu, DB15 -
DB12. Những khả năng được định nghĩa như sau:
• 0001 = MOVE.B
• 0011 = MOVE.W
• 0010 = MOVE.L
Nguồn EA và EA đích là cả hai trường 6-bit được chia thành hai, 3-bit mỗi trường. Một trường 3-bit,
được gọi là trường đăng ký, có thể đưa vào một giá trị 000-111, tương ứng với một trong địa chỉ
thanh ghi dữ liệu, D0 qua D7, và thanh ghi địa chỉ A0 qua A7. Các trường khác 3-bit là trường chế
độ. Trường mô tả hiệu quả này mô tả phương thức giải quyết vấn đề đang được sử dụng cho hoạt
động. Chúng tôi sẽ nhắc lại điểm này ở phần sau. Hãy xem một ví dụ thực tế. Xem xét các câu lệnh
MOVE.W #$0A55,D0
Điều hướng dẫn gì trông giống như sau khi được assemly thưc thi? Nó có thể giúp bạn tham khảo
một ngôn ngữ lập trình assemly thủ công, chẳng hạn như Programmer’s Reference Manual3 để hiểu
rõ hơn những gì đang xảy ra. Đây là những gì chúng tôi biết. Đó là một câu lệnh Move với kích
thước của dữ liệu chuyển giao là 16-bit, hoặc 1 từ nhớ. Như vậy, bốn bit quan trọng nhất của từ
opcode (D15 - D12) là 0.011. Hiệu quả địa chỉ nguồn (D5 - D0) là ngay lập tức, mà giải mã là 111
100. Các điểm đến địa chỉ có hiệu quả (D11 - D6) là thanh ghi dữ liệu D0, mà giải mã là 000 000.
Gom tất cả những điều này lại với nhau, từ ngôn ngữ máy opcode là:
0011 000 000 111 100 , or $303C
Bản dịch từ 0011 000 000 111 100 (nhị phân) đến $ 303C (hex) có thể có vẻ như một chút bối rối
cho bạn bởi vì các trường bit của chỉ thị thường không định dạng dựa vào ranh giới 4-bit. Tuy nhiên,
nếu bạn tiến hành từ phải sang trái, nhóm bốn, bạn sẽ nhận được nó ngay mỗi lần.
Điều đó có phải là tất cả các yếu tố của hướng dẫn không? Không, bởi vì tất cả chúng ta biết vào
thời điểm này là nguồn gốc của một toán hạng cấp tốc, nhưng chúng tôi vẫn không biết những số
lượng trước mắt. Như vậy, chữ opcode cho bộ vi xử lý rằng nó đã đi ra ngoài vào bộ nhớ một lần
nữa và lấy một phần khác của các toán hạng nguồn. Kể từ khi chế độ giải quyết có hiệu quả các D0
thanh ghi đích, có thanh ghi dữ liệu trực tiếp, không cần lấy bất kỳ thông tin bổ sung từ bộ nhớ bởi

vì tất cả các thông tin đó là cần thiết để xác định điểm đến được chứa trong các từ op-code của chính
nó. Do đó, hướng dẫn đầy đủ trong bộ nhớ sẽ là $ 303C 0A55. Điều này được minh họa trong hình
7.15.
Bây giờ, giả sử rằng hướng dẫn sử dụng hai địa chỉ tuyệt đối cho có hiệu quả nguồn địa chỉ và điểm
đến địa chỉ có hiệu quả
MOVE.W $0A550000,$1000BB00
Ngôn ngữ máy này từ op-sẽ giải mã là 0011 001 111 111 001, hoặc $ 33F9. Chúng tôi phải làm gì?
Một lần nữa, câu trả lời là không. Điều này là do vẫn còn có hai địa chỉ tuyệt đối mà cần phải được
lấy từ bộ nhớ. Các hướng dẫn hoàn chỉnh trông giống như
$33F9 0A55 0000 1000 BB00.
Các hướng dẫn hoàn chỉnh chiếm tổng cộng năm từ 16-bit của bộ nhớ và đòi hỏi bộ xử lý để làm cho
bộ nhớ năm quá trình xử lý riêng biệt cho câu lệnh. Điều này được minh họa trong hình 7.16.
Sắp xếp từ
Chủ đề cuối cùng mà chúng ta cần trang trải để tự chuẩn bị cho các nhiệm vụ lập trình trước chúng
ta là sự liên kết của từ trong bộ nhớ. Chúng tôi xúc tiến về chủ đề này sớm hơn trong bài học nhưng
nó đáng giá để xem lại khái niệm. Nhớ lại rằng chúng
tôi có thể địa chỉ byte riêng trong một từ bằng cách sử
dụng địa chỉ bit ít nhất là đáng kể, A0, để cho biết mà
byte chúng tôi đang quan tâm. Tuy nhiên, những gì sẽ
xảy ra nếu chúng tôi cố gắng để truy cập vào một từ
hoặc từ một giá trị lâu dài trên một byte lẻ ranh giới?
Hình minh hoạ 7.17 giới thiệu vấn đề.
Để lấy một từ nằm trên ranh giới byte lẻ bộ vi xử lý sẽ phải làm cho hai 16-bit và sau đó loại bỏ
phần bóng các bộ phận của cả hai từ chính xác đọc dữ liệu. Một số bộ xử lý có thể làm được điều
này. Đây là một ví dụ về phương thức truy cập không liên kết mà chúng tôi thảo luận trước đó. Nói
chung, loại hình này truy cập là rất tốn kém về hiệu quả xử lý. Các 68k không thể thực hiện thao tác
này và nó sẽ tạo ra một ngoại lệ trong nội bộ nếu gặp nó. Các lập trình viên assemly sẽ không giải
quyết được nó. Đây là một lỗi thời gian chạy. Cách chữa là để không bao giờ chương trình một từ
hoặc một hoạt động từ lâu trên một byte lẻ ở ranh giới bộ nhớ.
Đọc sách tham khảo dành cho lập trình viên

Các nhiệm vụ khó khăn nhất mà bạn sẽ phải đối mặt khi bạn đặt ra để viết một chương trình
assembly là cố gắng để hiểu được nội dung cuốn sách của nhà sản xuất. Sách tham khảo dành cho
lập trình viên Motorola 68k được viết bằng những gì chúng ta có thể hào phóng gọi là "một phong
cách khá ngắn gọn" Đó là một tham chiếu cho những người đã biết làm thế nào để viết một chương
trình ngôn ngữ assembly chứ không phải là một công cụ học tập cho sinh viên lập trình, người đang
cố gắng tìm hiểu các phương pháp. Từ điểm trên, bạn sẽ cần của Sách tham khảo dành cho lập trình
viên, hoặc một cuốn sách tốt về lập trình bằng ngôn ngữ assembly 68K, tương tự như sách giáo khoa
clements2. Tuy nhiên, sách giáo khoa không phải là đặc biệt hiệu quả nếu nói đến ghi chương trình
và cần tham chiếu thuận tiện, như là sách tham khảo của lập trình viên. May mắn là, nó rất dễ dàng
để có được một bản sao miễn phí của sách tham khảo, hoặc từ freescale, hoặc của chúng trang web
Tổng công ty ( xem tham chiếu chương cho URL ).
Vì vậy, giả dụ như bạn có sách trước mặt bạn, chúng ta hãy tham gia khoá học nhanh trong hiểu biết
những gì đội ngũ nhân viên ghi kỹ thuật của Motorola đang cố cho bạn biết. Văn bản sau giống bố
trí của trang tham chiếu cho lệnh.
1. Heading: ADDI Add Immediate ADDI
2. Operation: Immediate Data + Destination  Destination
3. Syntax: ADDI #<data>,<ea>
4. Attributes: Size = (Byte, Word, Long)
5. Description: Thêm dữ liệu ngay lập tức để các toán hạng đích và lưu trữ kết quả trong các
điểm đến địa điểm. Kích thước của hoạt động này có thể được quy định để được byte, từ hoặc dài.
Kích cỡ của dữ liệu ngay lập tức phù hợp với kích cỡ hoạt động. - Add the immediate data to the
destination operand and store the result in the destination location. The size of the operation may be
specified to be byte, word or long. The size of the immediate data matches the operation size.
6. Condition Codes:
X N Z V C
    
N được chọn nếu kết quả là âm. Còn lại xóa.
Z được chọn nếu kết quả là không. Còn lại xóa.
V được chọn nếu có quá trình tràn biến được xảy ra. Còn lại xóa.
C được chọn nếu quá trình tiếp nối được diễn ra. Còn lại xóa.

X được chọn giống như
7. Instruction format:
8. Instruction fields:
Trường kích thước - Chỉ định kích thước của hoạt động này:
9. Effective Address field:
Chỉ định toán hạng đích. Chỉ có dữ liệu hay thay đổi phương thức giải quyết được cho phép như:
10. Immediate field:(Dữ liệu ngay lập tức theo sau từ nhớ op-code)
Nếu kích thước = 00, vậy thì dữ liệu là byte mệnh lệnh thấp của từ nhớ tức thì.
Nếu kích thước = 01, vậy thì dữ liệu là toàn bộ từ nhớ tức thì.
Nếu kích thước = 10, vậy thì dữ liệu là tới hai từ nhớ tức thì.
1 Lệnh và thuật nhớ: ADDI—Add Immediate
2
Thao t ác: Immediate Data + DestinationDestination
Thêm dữ liệu trực tiếp đến nội dung của điểm đến địa chỉ có hiệu quả và để các
kết quả trở lại địa chỉ đích có hiệu quả.
3
Assembler syntax: ADDI #(data),<ea>
Điều này giải thích làm thế nào lệnh được viết bằng ngôn assembly. Thông báo rằng có một
opcode đặc biệt cho một tiện ích hướng dẫn ngay lập tức, ADdi hơn là ADD, mặc dù bạn vẫn
phải
chèn dấu # trong trường toán hạng nguồn.
4
Các thuộc tính: Byte, từ nhớ hoặc từ nhớ dài (long) Bạn có thể thêm một byte, từ nhớ hoặc từ
nhớ dài. Nếu bạn bỏ qua các B, W hoặc sửa đổi L. Sẽ mặc định được. W.
5
Mô tả: Bảo những gì mà lệnh thực hiện.
Đây là hy vọng của bạn tốt nhất của cố gắng để hiểu những gì giảng dạy là tất cả vì nó chỉ có
thực sự ngữ pháp tiếng Anh trên trang.
6
Điều kiện mã:

Danh sách các mã điều kiện mà bị ảnh hưởng bởi lệnh.
7
Hướng dẫn định dạng:
Làm thế nào hướng dẫn ngôn ngữ máy được tạo ra. Lưu ý rằng chỉ có một địa chỉ có hiệu
quả cho lệnh này.
8
Trường địa chỉ hiệu quả:
Các phương thức địa chỉ có hiệu lực được phép để được lệnh này. Nó cũng cho thấy chế độ
và đăng ký giá trị cho địa chỉ có hiệu quả. Lưu ý rằng một địa chỉ đăng ký không được phép
như là điểm đến địa chỉ có hiệu quả, cũng không phải là một giá trị dữ liệu ngay lập tức.
Cũng thông báo rằng hai chế độ địa chỉ liên quan đến việc truy cập chương trình, PC, cũng
không được phép sử dụng với lệnh này.
Vẽ lưu đồ
Chương trình assembly, do bản chất cấu trúc của chúng rất cao, là những ứng viên tốt để sử dụng lưu
đồ để trọ giúp lập kế hoạch cấu trúc của một chương trình. Nói chung, lưu đồ thì không được dung
để lập kế hoạch chương trình viết ngôn ngữ bậc cao như là C hoặc C + +, tuy nhiên, lưu đồ vẫn còn
rất hữu ích cho lập kế hoạch chương trình assembly.
Trong việc tạo ra lưu
đồ, chúng ta sử dụng
hình chữ nhật đại diện
cho " thao tác. "
Thao tác có thể là một
lệnh, vài lệnh, hoặc
chương trình con ( gọi
hàm ).
Hình chữ nhật được kết
hợp với làm điều gì đó.
Chúng ta sử dụng hình
kim cương đại diện cho
điểm quyết định (luồng

điều khiển chương
trình), và sử dụng mũi
tên để luồng chương
trình thể hiện. Hình
7.18 là lưu đồ đơn giản
ví dụ máy tính khởi
động chương trình.
Lưu đồ bắt đầu với thao
tác " thiết lập môi trường". Việc này có thể là một lệnh hoặc vài chục lệnh. Một khi môi trường được
thành lập thao tác kế tiếp là " chạy chính nó-thử nghiệm". Một lần nữa, điều này có thể nghĩa là một
lệnh nào hoặc nhiều lệnh, chúng tôi không biết. Nó phụ thuộc vào ứng dụng. Bước quyết định là đợi
nhập liệu từ bàn phím. Chương trình quét bàn phím rồi thử nghiệm để xem nếu phím đã được gõ.
Nếu không, nó quay lại ( vòng lặp ) và thử lại. Nếu phím đã được gõ, chương trình sẽ diễn giải tổ
hợp phím và tiếp tục.
Luồng - biểu đồ là một công cụ rất mạnh đã giúp bạn lập kế hoạch chương trình của bạn. Thật đáng
tiếc, nhất sinh viên ( và nhiều lập trình viên chuyên nghiệp ) lấy " mã tấn công " phương pháp và chỉ
nhảy vào và ngay lập tức bắt đầu ghi mã, nhiều như ghi tiểu thuyết. Đây có lẽ giải thích vì sao hầu
hết lập trình viên mặc giày xăng - đan thay vì bóng rổ giầy đế mềm với đăng - ten tháo, nhưng đó là
khác vấn đề hoàn toàn.
Viết chương trình assembly
Nhớ câu nổi tiếng của Dicaprio Leonardo trong phim Titanic, " tôi là vua của thế giới !" Trong việc
lập trình ngôn ngữ assembly bạn là quân chủ chuyên chế của máy tính thế giới. Không gì có thể có
thể ngăn bạn làm sai mã một cách ngớ ngẩn. Chẳng hề có loại kiểm tra hoặc trình biên dịch cảnh
báo. Chỉ bạn và máy, mano mano. Để ghi chương trình trong hợp ngữ, bạn phải nhận thức liên tục
về trạng thái của hệ thống. Bạn phải ghi nhớ có bao nhiêu bộ nhớ bạn có và nó nằm ở đâu; vị trí của
thiết bị ngoại vi của bạn và làm thế nào để truy cập chúng. Tóm lại, bạn điều khiển mọi thứ và bạn
chịu trách nhiệm về mọi thứ.
Nhằm các mục đích có thể ghi và thi hành chương trình trong ngôn ngữ assembly 68 K, chúng tôi sẽ
không thực sự sử dụng bộ xử lý 68 K. Để làm việc này bạn sẽ cần máy tính được dựa trên dòng bộ
xử lý 68 k, chẳng hạn ban đầu như Apple MacIntosh®. Chúng tôi sẽ tiếp cận theo một cách khác.

Chúng tôi sẽ sử dụng chương trình được gọi là bộ mô phỏng tập câu lệnh ( ISS ) để thay thế bộ xử lý
68 K.
Về mặt thương mại Isss sẵn có có thể bằng giá với $10,000 nhưng của chúng tôi là miễn phí. Chúng
tôi thật may mắn là hai mô phỏng rất tốt đã được viết cho bộ xử lý 68.000. Các mô phỏng đầu tiền,
được phát triển bởi clements4 và đồng nghiệp của anh ấy ở Đại Học của Teesside, ở Vương quốc
Anh, có thể là tải xuống từ trang web của anh ấy.
Kelley
5
phát triển một mô phỏng thứ hai, gọi là Easy68K. Đây là một giả lập mới hơn và có nhiều hỗ
trợ khắc phục lỗi thiếu phong phú, trong phiên bản Easy68K. Cả hai mô phỏng được thiết kế để chạy
dưới hệ điều hành Windows ® Ngoài ra, Easy68K đã được biên soạn dành cho Windows 32-bit, do
đó, nó có một cơ hội tốt hơn chạy dưới Windows 2000, XP và như vậy, mặc dù, các giả lập Teesside
có vẻ là hợp lý cư xử tốt hơn các phiên bản hiện đại hơn của Windows.
Các mô phỏng được gần gũi hơn với môi trường thiết kế tích hợp (IDE). Chúng bao gồm một trình
soạn thảo văn bản, lắp ráp, mô phỏng và gỡ rối trong một gói. Các mô phỏng giống như một máy
tính và debuggercombined. Bạn có thể làm rất nhiều các hoạt động dò lỗi mà bạn đang sử dụng đến,
chẳng hạn như
• nhìn trộm và thúc dục bộ nhớ
• kiểm tra và sửa đổi thanh ghi
• thiết lập điểm dừng
• chạy từ hoặc tới điểm dừng
• một bước và xem thanh ghi
Nói chung, bước để tạo ra và chạy chương trình assembly là đơn giản và chyển tiếp thẳng.
1. Sử dụng trình soạn thảo văn bản ASCII-only ưa chuộng của bạn, hoặc một bao gồm với gói
ISS, tạo ra nguồn của bạn chương trình và lưu trong định dạng tập tin DOS 8.3 cũ. Chắc chắn
sẽ sử dụng máy nhánh số .x68. Cho ví dụ, lưu chương trình của bạn như myprog.x68. Trình
soạn thảo đi cùng chương trình sẽ tự động nối hậu tố x68 cho tập tin của bạn.
2. Chương trình assembly sử dụng trình dịch assembler bao gồm. Trình dịch assembler sẽ tạo ra
tập tin ngôn ngữ máy tính tuyệt đối bạn có thể chạy với giả lập này. Nếu chương trình
assembler của bạn không có lỗi, bạn sau đó sẽ có thể chạy nó trong mô phỏng này. Trình

dịch assembler thực sự tạo ra hai tập tin. Tập tin nhị phân tuyệt đối và listfile. Listfile đưa
chương trình nguồn gốc bạn cho bạn xem và tập tin ngôn ngữ máy tính hệ thập lục phân nó
tạo ra. Nếu có bất cứ lỗi trong tập tin nguồn của bạn, lỗi sẽ được chỉ ra trên listfile đầu ra.
Trong trình dịch assembler Teesside, chương trình ngôn ngữ assembly chạy trên một máy tính mô
phỏng với 1M byte bộ nhớ chiếm dải địa chỉ ảo của 00.000 $. . . $ FFFFF. Các mô phỏng Easy68K
chạy trong một không gian địa chỉ đầy đủ 16. Các gói phần mềm giả lập Teesside là không phải là
không có một số nhỏ
thói quen, nhưng nói chung, đó là cư xử tốt khi chạy trong Windows.
Để chương trình trong ngôn ngữ assembly bạn nên là một lập trình viên có thẩm quyền. Bạn nên đã
có một số lớp lập trình và hiểu lập trình cấu trúc và cấu trúc dữ liệu. lập trình ngôn ngữ assembly có
thể có vẻ rất lạ lúc đầu, nhưng nó vẫn còn lập trình. Trong khi C và C + + là ngôn ngữ dạng tự do,
lắp ráp, ngôn ngữ là rất có cấu trúc. Ngoài ra, có theo dõi tài nguyên của bạn hay không là tùy ở
bạn Không có trình biên dịch có sẵn để làm phân bổ tài nguyên cho bạn.
Đừng bị lấn át bằng số opcodes và toán hạng là một phần của 68k, hoặc bất kỳ bộ xử lý của ISA.
Điểm thực sự ở đây là bạn có thể viết các chương trình tương đối hợp lý bằng cách sử dụng chỉ là
một tập hợp con của các hướng dẫn có thể và phương thức giải quyết. Không bị quá tải bởi số lượng
các hướng dẫn mà bạn có thể có thể sử dụng. Nhận viết chương trình thoải mái bằng cách sử dụng
một vài hướng dẫn và giải quyết các chế độ mà bạn hiểu và sau đó bắt đầu để tích hợp các hướng
dẫn khác và giải quyết chế độ khi bạn cần một cái gì đó hiệu quả hơn, hoặc chỉ muốn mở rộng cách
của chúng tôi.
Như các vấn đề lập trình mà bạn sẽ được làm việc trên trở nên có liên quan đến tự nhiên, bạn sẽ xem
xét để được hướng dẫn hiệu quả hơn và có hiệu quả các phương thức giải quyết vấn đề đó sẽ làm cho
công việc của bạn dễ dàng hơn và hiệu quả hơn trong một chương trình. Như bạn sẽ sớm khám phá
khi chúng ta nhìn vào kiến trúc máy tính khác nhau, rất ít lập trình viên hoặc trình biên dịch sử dụng
mọi lệnh trong tập lệnh. Hầu mọi lúc, tập hợp con nhỏ của lệnh sẽ hoàn thành việc hoàn toàn tốt.
Tuy nhiên, mỗi một lần trong một thời gian, vấn đề phát sinh mà chỉ làm cho một số hướng dẫn tối
nghĩa để solve.
Mô phỏng mã tác vụ
Có thực sự hai kiểu opcodes bạn có thể sử dụng trong chương trình của bạn. Đầu tiên là tập hợp các
mã tác vụ đó là lệnh thực tế được sử dụng bởi 68000 bộ xử lý. Chúng thiết lập 68 K ISA (kiến trúc

tập lệnh). Các thiết lập thứ hai được gọi là mô phỏngmã tác vụ, hay giả opcodes. Chúng được đặt
vào trong chương trình của bạn cũng giống như mã tác vụ thực sự, nhưng chúng là lệnh thật sự đến
trình dịch assembly nói ra cách để dịch chường trình assembly.Think của giả tác vụ đúng như bạn sẽ
nghĩ về trình biên dịch chỉ thị và câu lệnh #define.
Mô phỏng mã tác vụ (Pseudo-ops) còn được gọi là chỉ thị của trình dịch assembly. Chúng được sử
dụng để giúp làm cho chương trình dễ đọc hơn hoặc để cung cấp thông tin bổ sung cho trình dịch
asembly về cách bạn muốn chương trình xử lý. Điều quan trọng là phải nhận ra về mặt thương mại
sẵn có, công nghiệp - sức mạnh trình dịch hợp ngữ là hoàn toàn như phức tạp như bất kỳ trình biên
dịch hiện đại. chúng ta hãy nhìn vài mô phỏng mã tác vụ này
• ORG (thiết lập nguồn gốc): Các ORG pseudo-op cho biết các trình dịch asembly nơi trong
bộ nhớ để bắt đầu
lắp ráp chương trình. Điều này không nhất thiết mà chương trình có thể được nạp vào bộ
nhớ, nó chỉ nói trình dịch assembly, nơi bạn có ý định cho nó chạy. Nếu bạn bỏ qua các câu
lệnh ORG, chương trình sẽ dịch assembly để chạy bắt đầu từ vị trí bộ nhớ 00.000 $. Từ
phạm vi bộ nhớ từ 00.000 $ $ 003FF được dành riêng cho các vectơ hệ thống, chúng tôi sẽ
thường "ORG" chương trình của chúng tôi để bắt đầu tại địa chỉ bộ nhớ 00.400 $. Do đó,
dòng đầu tiên của bạn chương trình nên được
<label> ORG $400 <*comment>
Các chỉ thị pseudo-op tiếp theo được đặt ở phần cuối của file nguồn của bạn. Nó có hai chức năng.
Trước tiên, nó cho trình dịch asembly ngăn chặn lắp ráp tại điểm này và, thứ hai, nó cho các mô
phỏng nơi để tải các chương trình vào bộ nhớ.
• END (kết thúc file nguồn): Mọi thứ sau END được bỏ qua. Định dạng:
<no label> END <address>
Lưu ý rằng chỉ thị ORG và END được bổ sung. Chỉ thị ORG bảo trình dịch assembly như thế nào
để giải quyết địa chỉ tham chiếu ; trong thực tế, nơi bạn định cho chương trình để chạy. Ngừng chỉ
thị ra chỉ thị trình nạp ( bộ phận của simulator ) nơi để đặt mã chương trình trong bộ nhớ. Hầu mọi
lúc địa chỉ của ORG và ngừng sẽ là giống nhau, nhưng chúng không phải vậy. Rất có khả năng là
chương trình sẽ được nạp vào chỉ ở một chỗ thôi rồi dời đi khác khi đến lúc để chạy. Đối với mục
đích của chúng tôi, bạn sẽ thường bắt đầu chương trình của bạn với :
ORG $400 vả kết thúc với END $400

EQU (chỉ thị tương đương): Việc đánh đồng pseudo-op giống hệt với “#define” trong C. Nó cho
phép
để bạn cung cấp một tên tượng trưng cho một giá trị không đổi. Định dạng:
<label> EQU <expression> <*comment>
Các biểu hiện có thể là một biểu thức toán học, nhưng rất có thể nó sẽ chỉ là một số. Bạn cũng có thể
sử dụng ngang nhau chỉ để tạo ra một giá trị mới từ các giá trị biểu tượng khác tượng trưng. Tuy
nhiên, các giá trị của các biểu tượng khác phải được biết đến tại thời biểu tượng mới đang được đánh
giá. Điều này có nghĩa rằng bạn không thể có chuyển tài liệu tham khảo.
Việc đánh đồng chỉ thị, giống như "# define" chỉ thị trong C và C + +, được hướng dẫn để trình dịch
asembly C thay thế các giá trị số cho tên tượng trưng trong file nguồn của bạn. Ví dụ,
Bit0_test EQU $01 * Isolate data bit 0
ANDI.B #Bit0_test,D0 * Is bit 0 in D0 = 1?
sẽ có nhiều ý nghĩa với bạn hơn:
ANDI.B #$01,D0 * Magic numbers
đặc biệt là sau khi bạn đã không nhìn vào mã trong nhiều ngày.
• SET (đặt biểu tượng): SET giống như EQU có thể sẽ được sử dụng để xác định lại một biểu
tượng giá trị khác về sau này. Định dạng
<label> SET <expression>
Chỉ thị lưu trữ dữ liệu
Nhóm tiếp theo của pseudo-ops được gọi là chỉ thị lưu trữ dữ liệu. Mục đích của chúng là để hướng
dẫnlắp ráp để phân bổ khối của bộ nhớ và có thể khởi tạo bộ nhớ có giá trị.
• DC (xác định hằng số): Tạo ra một khối bộ nhớ chứa dữ liệu giá trị được liệt kê trong tập tin
nguồn. định dạng là:
<label> DC.<SIZE> <item>,<item>,
Ví dụ:
error_msg DC.B ‘Error 99’,$0D,$0A,$00 *error message
Chuỗi văn bản đó là được đặt trong dấu nháy đơn là thông dịch bằng trình dịch assmbly như chuỗi
của ký tự ASCII. Vì vậy, chỉ thị này tương đương với ghi
error_msg DC.B $45,$72,$72,$6F,$72,$20,$39,$39,$0D,$0A,$00
Như bạn thấy, sử dụng dấu ngoặc đơn làm cho ý định của bạn dễ hiểu hơn. Trong trường hợp này,

các vị trí bộ nhớ liên kết label, error_msg, sẽ có các byte đầu tiên của chuỗi, $ 45.
• DCB (xác định khối liên tục): Khởi tạo một khối bộ nhớ với giá trị như nhau. chiều dài là n
số byte, từ nhớ hay từ nhớ dài. Định dạng
<label> DCB.<size> <length>,<value>
• DS (xác định lưu trữ): Tạo ra một khối khởi tạo bộ nhớ. Sử dụng điều này nếu bạn cần xác
định một khu vực lưu trữ mà sau này bạn sẽ sử dụng để lưu dữ liệu. định dạng là:
<label> DS.<size> <length>
• OPT (đặt tùy chọn): Bảo các nhà lắp ráp như thế nào bạn muốn trình dịch asembly tạo ra
các mã chương trình của bạn ở những nơi bạn chưa rõ ràng và chỉ dẫn nó vào cách bạn muốn
định dạng listfile.
Các lựa chọn duy nhất đó là đáng chú ý ở đây là tùy chọn CRE. Tùy chọn này cho trình dịch
assembly
để tạo ra một danh sách các cross-references trên listfile này. Đây là một trợ giúp vô giá khi nói đến
thời gian để debug chương trình của bạn. Ví dụ, kiểm tra các khối mã trong trường hợp 1.
Trường hợp 1: Listfile mà không có sự lựa chọn CRE

×