banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành Windows ASM cho newbie (dich tu` Art of Assembly)  XML
  [Programming]   ASM cho newbie (dich tu` Art of Assembly) 27/01/2009 00:54:24 (+0700) | #1 | 167580
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Em là thành viên mới của HVA
Đầu tiên em xin chúc tất cả các thành viên trong forum một năm mới an khang thịnh vượng (văn dốt nên không biết nói gì smilie )
Bài này em post lên cho các bạn newbie, mong các zom đừng cười vì trình độ ASM của em cũng tạm được. Em thấy mấy thằng New khổ quá học cái này chẳng biết đâu mà lần nên post lên smilie .

Bài này được dịch từ "Art of Assembly" cuốn sách nổi tiếng về ASM các bạn có thể download tai http://www.ebook.edu.vn

Muốn đọc hiểu các phần này các bạn nên hiểu rõ về hệ nhị phân và hexa (kiến thức căn bản của toán học) rất quan trọng hệ thống máy tính

Phần 1.5: Các phép toán trên bit

Có 4 phép toán logic chính mà chúng ta cần biểu diễn trên hệ nhị phân và hệ hexa là: AND, OR, XOR (phép loại trừ OR), và NOT. Không giống như các phép tính đại số, máy tính hexa (bỏ túi) không cần thiết để thực hiện các phép toán này. Nó thường dễ làm hơn khi thực hiện bằng tay hơn là thực hiện bằng các thiết bị điện tử để tính toán chúng. Phép logic AND là phép toán đôi (gồm chính xác là hai toán hạng). Các toán hạng đó là một chữ số của hệ nhị phân. Phép toán AND là:
0 and 0 = 0
0 and 1 = 0
1 and 0 = 0
1 and 1 = 1

Một cách ngắn gọn để biểu diễn phép toán logic AND là dùng bảng chân trị. Một bảng chân trị được đưa ra dưới dạng sau:



Đây cũng chỉ như là bảng cửu chương bạn đã từng học ở trường tiểu học. Các cột bên trái và dòng đầu tiên biểu diễn các giá trị đầu vào của phép AND. Những giá trị được định ở những chỗ giao nhau của hàng và cột (cho mỗi cặp giá trị đầu vào) là kết quả của phép logic AND cho hai giá trị đầu vào đó. Trong Tiếng And, phép toán AND được nói là, "Nếu toán hạng thứ 1 là 1 và toán hạng thứ 2 cũng là 1 thì kết quả là 1, còn lại kết quả là 0"

Một điều quan trọng bạn cần chú ý về phép logic AND là bạn có thể dùng nó để làm cho kết quả là 0 như ý muốn. Nếu một trong các toán hạng là 0, thì kết quả luôn là không bất chấp toán hạng kia là cái gì. Trong bảng chân trị trên, ví dụ như, hàng chứa 0 được đặt vào và cột chứa 0 được đặt vào chỉ chứa kết quả là 0. Đảo lại, nếu một toán hạng là 1, thì kết quả chính là toán hạng thứ hai. Đặc điểm này của AND là rất quan trọng khi làm việc với các chuỗi bit và khi chúng ta muốn ép một bit riêng biệt nào đó trong chuỗi về 0. Chúng ta sẽ nghiên cứu cách sử dụng này của logic AND trong phần tới.

Phép toán logic OR cũng là một phép toán đôi. Nó được định nghĩa như sau:

0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 1

Bảng chân trị của OR được đưa ra dưới dạng sau:



Thông thường, phép logic OR được nói là “Nếu toán hạng đầu tiên hoặc toán hạng thứ hai là (hoặc cả đôi) là 1, kết quả là 1; còn lại kết quả là 0”. Nó cũng được biết như là một phép toán bao hàm-OR.

Nếu một trong các toán tử của phép logic OR là 1, kết quả luôn luôn là 1 bất kêt toán hạng thứ 2 là cái gì. Tương tự phép logic AND, đây cũng là mặt quan trọng của phép logic OR sẽ rất hữu dụng khi làm việc với các chuỗi bit.

Chú ý rằng có một sự khác nhau giữa dạng bao hàm logic OR và định nghĩa chuẩn Tiếng Anh. Xét câu nói “Tôi đang đi tới cửa hàng hoặc tôi đang đi tới công viên”. Câu nói này có hàm ý là người nói đang đi tới cửa hàng hoặc công viên nhưng không phải là cả hai. Vì vậy, phiên bản Tiếng Anh cho phép logic OR khác với phép bao hàm-OR; nó giống hơn với phép loại trừ logic OR.

Phép logic XOR (loại trừ-OR) cũng là phép toán đôi. Nó được định nghĩa như sau:

0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

Bảng chân trị của XOR được đưa ra dưới dạng sau:




Trong Tiếng Anh, phép toán logic XOR được nói là, “Nếu toán tử đầu tiên hoặc toán tử thứ hai nhưng không phải cả đôi, là 1, kết quả là 1; còn lại kết quả là 0”. Chú ý rằng phép loại trừ-OR đúng với định nghĩa Tiếng Anh hơn là phép logic OR.

Nếu một trong các toán hạng của phép loại trừ-OR là 1, kết quả luôn là đảo ngược của toán hạng thứ 2; đó là, nếu toán hạng 1 là 1, kết quả là 0 nếu toán hạng 2 là 1, và kết quả là 1 nếu toán hạng 2 là 0. Nếu toán hạng đầu tiên là 0, thì kết quả chính là toán hạng 2. Đặc điểm này dùng để đảo ngược một chuỗi bit.

Phép toán logic NOT là một phép toán đơn (chỉ chấp nhận 1 toán hạng) . Đó là:

NOT 0 = 1
NOT 1 = 0

Bảng chân trị của NOT được đưa ra dưới dạng sau:



[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 27/01/2009 04:05:07 (+0700) | #2 | 167588
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
e hèm sau đây là phần 1.6

Phần 1.6:Các phép toán logic trên hệ nhị phân và chuỗi bit


Như đã miêu tả ở phần trước, các hàm logic với toán hạng là các bit đơn. Vì 8086 sử dụng các nhóm bit 8, 16, 32, chúng ta cần mở rộng định nghĩa của các hàm đó để thực hiện với số lượng nhiều hơn hai bit. Hàm logic trên 8086 thực hiện từng bit tương ứng với nhau (bit-by-bit). Cho hai giá trị, hàm logic sẽ thực hiện ở các bit 0 các giá trị này và cho giá trị ở bit 0 của kết quả. Sau đó nó lại thực hiện trên các bit 1 và cho kết quả tại bit 1 của kết quả. Ví dụ như, nếu bạn muốn tính toán logic AND của hai số 8 bit sau, bạn sẽ thực hiện phép logic AND trên từng cột độc lập khác nhau:

1011 0101
AND
1110 1110
---------
1010 0100

Dạng bit-by-bit này cũng được áp dụng một cách tương tự cho các phép toán logic khác.

Vì chúng ta đã định nghĩa phép toán logic trong giới hạn của các giá trị nhị phân, bạn sẽ thấy dễ dàng hơn nhiều để biểu diễn các phép toán logic trên hệ nhị phân hơn là các hệ cơ số khác. Vì vậy, nếu bạn muốn thực hiện một phép logic trên hai giá trị thập phân, đầu tiên bạn nên chuyển chúng thành các giá trị nhị phân tương ứng. Rồi áp dụng các phép logic cơ sở trên các số nhị phân này.

Khả năng để ép các bit thành 0 hay 1 sử dụng các phép logic AND/OR và khả năng đảo ngược chuỗi bit sử dụng logic XOR là một điều quan trong khi làm việc với các chuỗi bit . Các phép toán này cho phép bạn làm biến đổi một bit (chuỗi bit) bất kỳ tùy thích mà không gây ảnh hưởng tới các bit còn lại. Ví dụ như, nếu bạn có một giá trị 8-bit “X” và bạn muốn chắc chắn rằng bit 4 đến bit 7 là các số 0, bạn có thể sử dụng phép logic AND cho giá trị “X” với 0000 1111. Phép logic AND bitwise này sẽ ép cho 4 bit H.O. ( 4 bit đầu của một byte còn gọi là nibble H.O.) thành 0 và vẫn giữ nguyên 4 bit L.O. Tương tự như vậy, bạn có thể ép L.O. Bit của “X” thành 1 và đảo ngược bit 2 của “X” bằng cách sử dụng logic OR cho “X” với 0000 0001 và sử dụng logic XOR cho “X” với 0000 0100. Sử dụng các phép logic AND,OR, và XOR để làm các chuỗi bit theo ý thích thì cũng như là làm mặt nạ bit. Chúng ta sử dụng điều kiện mặt nạ bởi vì chúng có thể sử dụng các giá trị nào đó để làm “mặt nạ ngoài” cho bit nào đó từ các phép toán khi ép các bit thành 0, 1, hay đảo ngược chúng.


[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 27/01/2009 05:33:01 (+0700) | #3 | 167595
[Avatar]
dungth02
Member

[Minus]    0    [Plus]
Joined: 25/12/2008 21:33:01
Messages: 72
Offline
[Profile] [PM]
Là bạn dịch hai ai dịch ra vậy bạn? Bạn nên tham khảo cách trình bày một bài tutorials ở trong Box "Thủ thuật reverse engineering" để trình bài viết của mình tốt hơn.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 27/01/2009 05:44:10 (+0700) | #4 | 167596
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Là tui dịch đấy! đã nói đằng trên rùi chứ trình độ tiếng anh có hạn. Mà vào cái box đó để làm gì chỉ toàn hướng dẫn crack smilie
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 27/01/2009 05:45:36 (+0700) | #5 | 167597
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Tối nay tui sẽ post tiếp sai sót chỗ nào mong mọi người giúp đỡ
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 27/01/2009 08:20:37 (+0700) | #6 | 167600
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Tui muốn nói với các bạn rằng tui chỉ dịch những phần quan trọng của các chương vì vậy các bạn bỏ quá cho smilie
Những phần tui chưa hiểu nghĩa Tiếng Anh tui để trong ngoặc mong các bạn bổ sung.
Nhân tiện cho hỏi làm sao lấy được hình từ PC để post lên diễn đàn. Thanks

Phần 1.7: Số không dấu và có dấu

Cho tới lúc này, chúng ta vẫn coi các giá trị nhị phân như các giá trị không dấu. Số nhị phân ...00000 biểu diễn 0, ...00001 biểu diễn 1, ...00010 biểu diễn 2, và vân vân. Vậy còn các số âm? Giá trị có dấu đã được nhắc tới trong các phần trước và chúng ta cũng đã đề cập tới hệ phần bù của 2, nhưng chúng ta chưa thảo luận về cách biểu diễn số âm sử dụng hệ nhị phân. Đó là điều được nhắc tới trong tất cả phần này.

Để biểu diễn số âm sử dụng hệ nhị phân chúng ta phải đặt một giới hạn cho các số của chúng ta: chúng phải có một số lượng bit hữu hạn và được quy định. (As far as the 80x86 goes), đây không là quá nhiều sự giới hạn, sau cùng, 8086 chỉ có thể định địa giới hạn số lượng bit. Cho mục đích của chúng ta, chúng ta sẽ chỉ dùng một vài giới hạn của số bit là 8, 16, 32, hoặc vài cái khác nhỏ hơn.

Với một số lượng bit được quy định chúng ta chỉ có thể biểu diễn một số lượng đối tượng nào đó. Ví dụ như, với 8 bit chúng ta chỉ có thể biểu diễn 256 đối tượng khác nhau. Các giá trị âm cũng có thể là các đối tượng trong đó, nó giống như các số dương. Vì vậy, chúng ta sẽ sử dụng một vài giá trị trong 256 giá trị khác nhau để biểu diễn số âm. Trong thực tế, chúng ta đã sử dụng các số dương để biểu diễn các số âm. Để làm được điều tương tự như vậy, chúng ta sẽ lấy một nửa các giá trị dương để tổ hợp thành các giá trị âm và một nửa chúng ta giữ nguyên để cho giá trị dương. Vì vậy chúng ta có thể biểu diễn các giá trị âm từ -128..-1 và các giá trị dương từ 0..127 với 8 bit (1 byte) . Với một 16 bit (1 word) chúng ta có thể biểu diễn các giá trị trong vùng -32,768..+32,767. Với một 32 bit (1 doubble word) chúng ta có thể biểu diễn các giá trị trong vùng -2,147,483,648..+2,147,483,647. Tổng quát, với n bit chúng ta có thể biểu diễn các giá trị có dấu trong vùng -2^(n-1)..+2^(n-1)-1..

Okay, chúng ta có thể biểu diễn các giá trị âm. Vậy cách biểu diễn chúng như thế nào ? Có nhiều con đường, nhưng vi mạch 8086 sử dụng hệ phần bù của 2. Trong hệ thống phần bù vủa 2, bit H.O.là bit dấu. Nếu bit H.O. là 0, số đó là dương, nếu bit H.O. là 1, số đó là âm. Ví dụ:

Cho các số 16 bit:

8000h là số âm vì bit H.O. là 1.
100h là số dương vì bit H.O. là 0.
7FFFh là số dương
0FFFFh là số âm.
0FFFh là số dương.

Nếu bit H.O. là 0, thì số đó là dương và được lưu trữ như dạng nhị phân tiêu chuẩn. Nếu bit H.O. là 1, thì số đó âm và được lưu trữ trong hệ phần bù của 2. Để chuyển các số dương thành dạng âm của nó, dạng phần bù 2, bạn sử dụng các biến đổi sau đây:

1)Đảo ngược tất cả các bit áp dụng logic NOT
2)Cộng 1 vào kết quả đạt được

Ví dụ như, để làm thành 8 bit tương đương với -5:

0000 0101 5
1111 1010 Đảo ngược tất cả các bit
1111 1011 Cộng 1 vào kết quả đạt được

Nếu chúng ta lấy -5 và thực hiện phần bù 2 trên nó, chúng ta được giá trị ban đầu, 0000 0101, tương tự như vậy chúng ta thực hiện:

1111 1011 Phần bù 2 cho -5.
0000 0100 Đảo ngược tất cả các bit.
0000 0101 Cộng 1 vào kết quả đạt được(+5).

Các ví dụ sau sẽ đưa ra một vài giá trị có dấu và không dấu 16 bit:

7FFFh: +32767, Số dương lớn nhất 16 bit .
8000h: -32768, Số âm nhở nhất 16 bit.
4000h: +16,384.

Để chuyển các số trên thành dạng bù với chúng, làm như sau:

7FFFh:
0111 1111 1111 1111 +32,767t
1000 0000 0000 0000 Đảo ngược tất cả các bit (8000h)
1000 0000 0000 0001 Cộng 1 (8001h hay-32,767t)
8000h:
1000 0000 0000 0000 -32,768t
0111 1111 1111 1111 I Đảo ngược tất cả các bit(7FFFh)
1000 0000 0000 0000 Cộng 1(8000h hay -32768t)
4000h:
0100 0000 0000 0000 16,384t
1011 1111 1111 1111 Đảo ngược tất cả các bit (BFFFh)
1100 0000 0000 0000 Cộng 1 (0C000h hay -16,384t)

1100 0000 0000 0000 Add one (0C000h or -16,384t)

8000h được đảo ngược thành 7FFFh. Sau đó cộng 1 chúng ra được 8000h! Điều gì đang diễn ra ở đây? -(-32,768) là -32,768? Đương nhiên không. Vì giá trị +32,768 không thể được biểu diễn thành 1 số 16 bit có dấu, vì vậy chúng ta không thể lấy phần bù của giá trị âm nhỏ nhất. Nếu bạn cố gắng thực hiện phép toán này, vi mạch 8086 sẽ giải thích về sự tràn dấu.

(Why bother with such a miserable numbering system? Why not use the H.O. bit as asign flag, storing the positive equivalent of the number in the remaining bits? The answer lies in the hardware. As it turns out, negating values is the only tedious job). Với hệ thống phần bù của 2, hầu hết các phép toán đều dễ dàng như là hệ nhị phân. Ví dụ như, giả sử bạn thực hiện phép cộng 5+(-5). Kết quả là 0. Xét điều xảy ra khi chúng ta cộng hai giá trị trong hệ phần bù 2.

00000101
+
11111011
--------
1 00000000

Chúng ta kết thúc thì có bit thứ 9 bị mang ra ngoài (do byte chỉ chứa được 8 bit) và các bit còn lại là 0. Khi thi hành, nếu chúng ta bỏ qua bit bị mang ra ngoài bit H.O. thì cộng hai giá trị có dấu bù với nhau luôn luôn đúng. Điều này có nghĩa là chúng ta có thể sử dụng cùng một phần cứng cho cộng và trừ các giá trị có dấu và không dấu. Và không có trường hợp như thế này trên hệ cơ số khác.

Điều được mong chờ cuối cùng khi kết thúc phần này là, bạn sẽ không cần thực hiên phép toán phần bù của 2 bằng tay. Vi mạch 8086 cung cấp cho chúng ta một chỉ thị NEG(negate), dùng để thực hiện các phép toán này thay cho bạn. Hơn nữa, tất cả các máy tính bỏ túi hexadecimal sẽ thực hiện các phép tính này bằng cách nhấn các phím dấu (+/- hoặc CHS). Tuy nhiên thực hiện phép phần bù 2 bằng tay cũng khá dễ dang bạn nên biết cách làm nó.

Lại một lần nữa bạn nên chú ý các dữ liệu được biểu diễn bằng các tập các bit nhị phân phụ thuộc toàn bộ vào ngữ cảnh. Giá trị nhị phân 8 bti 1100 0000b có thể biểu diễn một ký tự IBM/ASCII, nó có thể biểu diễn giá trị không dấu là 192, hoặc nó có thể biểu diễn giá trị có dấu trong hệ thập phân là -64, vv. Như một lập trình viên, bạn cần phải sử dùng một cách hợp lý dữ liệu này.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 28/01/2009 01:04:16 (+0700) | #7 | 167624
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Tiếp tục nè
Phần 1.8: Sự mở rộng dấu và mở rộng không

ì dạng phần bù hai của số nguyên có một độ dài cố định, một vấn đề nhỏ nảy sinh. Điều gì xảy nếu bạn cần chuyển một giá trị phần bù hai 8 bit thành 16 bit? Vấn đề này, và mệnh đề ngược với nó (chuyển một giá trị 16 bit thành 8 bit) có thể được thực hiện qua phép toán mở rộng và co dấu. Tương tự như vậy, 8086 làm việc với một giá trị có độ dài được định rõ, thậm chí khi thi hành các giá trị nhị phân không dấu. Mở rộng không cho phép ban chuyển các giá trị không dấu có độ dài nhỏ thành giá trị không dấu có độ dài lớn hơn.

Xét giá trị “-64”. Giá trị phần bù hai 8 bit cho số này là 0C0h. Giá trị 16 bit tương đương của giá trị này là 0FFC0h. Bây giờ xét giá trị “64”. Bản 8 và 16 bit cho giá trị này là 40h và 0040h. Sự khác nhau giữa các số 8 và 16 bit được miêu tả bởi quy tắc sau: “Nếu số là âm, byte H.O. của số 16 bit chứa 0FFh; nếu số là dương, byte H.O. của 16 bit là chuỗi số 0”.

Mở rộng dấu một giá trị từ một số bit thành một lượng bit lớn hơn khá dễ dàng, chỉ cần sao chép bit dấu vào tất cả những bit được thêm vào trong định dạng mới. Ví dụ như, để mở rộng dấu một số 8 bit thành một số 16 bit, thật đơn giản sao chép bit 7 của số 8 bit vào trong các bit từ 8..15 của số 16 bit. Để mở rộng một số 16 bit thành một doubble word, đơn giản chỉ cần sao chép bit 15 vào các bit từ 16..31 của doubble word.

Mở rộng dấu được yêu cầu khi một giá trị có dấu thay đổi chiều dài. Thường bạn sẽ cần cộng một chuỗi byte thành một word. Bạn phải mở rộng một byte thành một word trước khi đưa vào tính toán ở nơi phù hợp sử dụng. Các phép toán khác (nhân và chia, trong trường hợp đặc biệt) phải yêu cầu mở rộng dấu tới 32 bit. Bạn không phải mở dấu giá trị không dấu.

Ví dụ về mở rộng dấu:




Để mở rộng dấu cho các giá trị byte không dấu bạn phải mở rộng 0 cho các giá trị đó. Mở rộng không rất dễ dàng - chỉ chứa không vào H.O. byten của toán hạng nhỏ hơn. Ví dụ như, để mở rộng không giá trị 82h thành 16 bit bạn chỉ cần cộng không một cách đơn giản vào byte H.O. dãy 0082h.



Co dấu, chuyển một giá trị với một số bit thành giá trị tương đương với số bit ít hơn, có một vài sự khó chịu. Mở rộng dấu không bao giờ sai. Cho một giá trị có dấu m bit bạn có thể luôn chuyển nó thành một giá trị n-bit (ở đây n>m) sử dụng mở rộng dấu. Thật không may, cho một giá trị n-bit, bạn không thể luôn luôn chuyển thành nó thành một số m bit nếu m < n. Ví dụ như, xét giá trị -448. Như một giá trị số hexa 16 bit, biểu diễn của nó là 0FE40h. Lượng của số này quá lớn để điền vào trong giá trị 8 bit. Đây là một ví dụ của điều kiện tràn dấu xảy ra khi chuyển đổi


Nếu bạn bắt gặp giá trị khác (≠ không hoặc 0FFh), bạn không thể co nó nếu không có sự tràn dấu. Cuối cùng, bit H.O. của giá trị kết quả của bạn phải hợp với mỗi bit mà bạn đã loại bỏ từ số ban đầu. Ví dụ (16 bit → 8 bit):

FF80h ----- có thể co thành 80h
0040h ----- có thể co thành 40h
FE40h ----- không thể co thành 8 bit.
0100h ----- không thể co thành 8 bit
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 28/01/2009 05:01:20 (+0700) | #8 | 167631
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Phù mệt quá được mấy bữa tết rãnh rỗi ngồi post giết thời gian smilie

Phần 1.9:Dịch và quay

Những phép toán logic khác áp dụng cho các chuỗi bit là phép dịch và quay. Có hai loại cho mỗi phép toán trên đó là dịch trái, quay trái, dịch phải, và quay phải. Các toán tử này rất hữu dụng cho các lập trình viên assembly.

Phép toán dịch trái chuyển mỗi bit trong một chuỗi bit về vị trí bên trái của nó:




Bit không được chuyển vào vị trí bit một, giá trị trước trong bit chuyển vào vị trí bit hai. Do đó, đương nhiên sẽ có hai câu hỏi nảy sinh rất tự nhiên: “Cái gì đi vào bit không ?” và “ Bit bảy sẽ đi đâu” đó là phụ thuộc vào ngữ cảnh. Chúng ta sẽ dịch giá trị 0 vào L.O. bit, và giá trị trước của bit bảy sẽ được mang ra ngoài khỏi phép toán này.

Chú ý rằng dịch trái một giá trị đồng nghĩa với nhân giá trị đó bằng hệ số đếm của nó. Ví dụ như, dịch một số thập phân một vị trí về bên trái (thêm 0 vào bên phải của số đó) thì cũng như nhân nó với 10 (cơ số):

1234 SHL 1 = 12340 (SHL 1 = dịch trái 1 vị trí)

Vì cơ số của hệ nhị phân là 2, dịch nó về bên trái là nhân nó với 2. Nếu bạn dịch một giá trị nhị phân về trái hai lần, thì bạn đã nhân nó với hai lần hai (nhân nó với bốn). Nếu bạn dịch một giá trị nhị phân về bên trái 3 lần, bạn nhân nó với 8 (2*2*2). Tổng quát, nếu bạn dịch một giá trị nhị phân n lần, bạn nhân giá trị đó với 2^n.

Phép dịch phải cũng làm việc theo cách tương tự như vậy, một điều khác là chúng ta sẽ chuyển dữ liệu theo hướng đối diện. Bit bảy chuyển vào bit sáu, bit sáu chuyển vào bit năm, bit năm chuyển vào bit bốn, ….Trong suốt quá trình một phép dịch phải, chúng ta sẽ chuyển không vào bit bảy, và bit không sẽ được mang ra ngoài phép toán:




Vì phép dịch trái là tương đương với nhân hai, và cũng không ngạc nhiên rằng phép dịch phải có thể so sánh một cách khập khểnh với chia cho hai (hay, tổng quát, là phép chia cho cơ số). Nếu bạn thực hiện dịch phải n lần, bạn sẽ chia số đó cho 2^n.

Có một vấn đề với phép dịch phải với điều chú ý của phép chia: như đã miêu tả ở trên một phép dịch phải chia không dấu cho 2. Ví dụ như, nếu bạn dịch một biểu diễn không dấu của 254 (0FEh) một ví trí về bên trái, bạn được 127 (07Fh), chính xác như những gì bạn mong chờ. Tuy nhiên, nếu bạn dịch biểu diễn của -2 (0FEh) về bên phải một vị trí bạn được 127 (07Fh), điều này không chính xác. Đây là vấn đề xảy ra bởi vì chúng ta dịch 0 vào bit bảy. Nếu giá trị bit bảy trước chứa 1, chúng ta đã thay đổi nó từ số âm sang số dương. Không một gì tốt đẹp khi chia cho 2. Để sử dụng phép dịch phải như một phép chia, chúng ta phải định nghĩa thêm một phép toán thứ ba: phép dịch phải số học. Một phép dịch phải số học cũng chỉ làm việc như phép dịch phải bình thường (logic dịch phải) với một điều khác: Thay thế cho dịch không vào bit bảy, phép dịch phải số học sẽ để lại bit bảy, trong suốt quá trình thực hiện phép toán nó không làm thay đổi giá trị của bit bảy:




Nói chung nó sẽ cho ra kết quả như bạn mong đợi. Ví dụ như, nếu bạn thực hiên một phép dịch phải số học trên -2(0FEh) bạn được -1 (0FFh). Tuy nhiên phép toán này luôn luôn cho phần nguyên của kết quả là số nguyên bé hơn hoặc bằng với kết quả thực. Dựa trên các kinh nghiệm với các ngôn ngữ lập trình bậc cao và tiêu chuẩn quy định về sự chia số nguyên, hầu hết mọi người đều cho rằng điều này có nghĩa là có một bộ phận luôn bị rút về không. Ví dụ như, nếu bạn áp dụng phép dịch phải số học trên -1 (0FFh), kết quả là -1, không phải là 0, -1 bé thua 0 vì vậy phép phải số học sẽ lấy kết quả là -1. Đây không phải là một lỗi trong phép toán dịch phải số học. Đây là cách điển hình cho định nghĩa phép chia số nguyên.Lệnh chia số nguyên của 8086 luôn cho ra kết quả này

Một đôi phép toán hữu dụng khác là quay trái và quay phải. Các phép toán này cũng như các phép dịch phải và trái với điểm khác biệt chủ yếu: bit được dịch ra ngoài được dịch vào trong bit kết thúc cuối cùng

Quay trái:




Quay phải:

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 28/01/2009 12:35:02 (+0700) | #9 | 167654
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Phần này cũng không quan trọng lắm nhưng có lẽ phần này là cơ sở cho các phần mềm nén dữ liệu nên post lên cho những ai quan tâm.

Phần 1.10:Dãy bit và dữ liệu gói

Mặc dù 8086 thực hiện tính toán hầu hết trên các loại dữ liệu byte, word, và double word, nhưng thông thường bạn sẽ cần làm việc với các loại dữ liệu sử dụng số bit không phải là 8, 16, 32. Ví dụ như, xét một ngày của dạng “4/2/88”. Nó đưa ra ba giá trị số biểu diễn ngày này: giá trị tháng, ngày, và năm. Tháng, đương nhiên, có giá trị từ 1..12. Nó sẽ yêu cầu ít nhất 4 bit (nhiều nhất 16 giá trị khác nhau) để biểu diễn tháng. Ngày ở trong khoảng 1..31 vì vậy nó sẽ cần 5 bit (nhiều nhất 32 giá trị khác nhau) để biểu diễn giá trị ngày. Với giá trị năm, cứ cho rằng chúng ta sẽ làm việc với giá trị trong vùng 0..99, yêu cầu 7 bit (có thể dùng để biểu diễn tới 128 giá trị khác nhau). Bốn cộng năm cộng bảy là 16 bit, hoặc hai byte. Thực tế, chúng ta có thể gói ngày của chúng ta trong hai byte hơn là sử dụng ba byte cho mỗi giá trị tháng, ngày, và năm. Sự lưu trữ một byte cho một dữ liệu lưu trữ, điều này có thể tốn bộ nhớ đáng kể nếu bạn cần lưu trữ nhiều dữ liệu ngày:




MMMM biểu diễn bốn bit làm giá trị tháng, DDDDD biểu diễn năm bit làm ngày, và YYYYYYY là bảy bit bao gồm giá trị năm. Mỗi sự thu nhặt của bit biểu diễn trong mỗi mục dữ liệu là một dãy bit. Tháng 4, ngày 2,1988 được biểu diễn như là 4158h:

0100 00010 1011000=0100 0001 0101 1000b hay 4158
4288

Mặc dù dữ liệu gói làm cho khoảng trống ít đi, nhưng chúng sẽ bị thực hiện chậm lại. Lý do? Nó đưa ra nhiều lệnh để thực hiện giải nén giữ liệu trong các dãy bit riêng biệt. Có nhiều thêm chỉ thị sẽ cộng vào thời gian thực hiện (và byte cộng vào để tiến hành lệnh); vì lý do đó, bạn phải xem xét cẩn thận với dữ liệu gói mà bạn lưu trữ. Ví dụ về dữ liệu gói có rất nhiều. Bạn có thể gói 8 giá trị boolean trong một byte, bạn có thể gói hai số BCD (số thập phân mã nhị phân) trong một byte....
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 29/01/2009 06:38:44 (+0700) | #10 | 167674
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Đây là phần cuối cùng trong chương 1, lần tới tui sẽ post các bài quan trọng trong chương 2

Phần 1.11: Bảng mã ASCII

Các ký tự ASCII (bao gồm phần mở rộng định nghĩa bởi IBM) được chia thành 4 nhóm mỗi nhóm 32 ký tự. 32 ký tự đầu tiên, mã ASCII từ 0 đến 1Fh (31), dạng các ký tự đặc biệt không thể in ra (non-printing characters) được gọi là các ký tự điều khiển. Chúng ta gọi các ký tự điều khiển bởi vì chúng thực hiện các điều khiển in/hiển thị khác nhau hơn là thực hiện các thao tác trên ký tự hiển thị. Ví dụ bao gồm carriage return (CR), làm cho ví trí con trỏ về vị trí bên trái của dòng ký tự, line feed (LF) (làm di chuyển con trỏ về một vị trí phía bên trái). Không may, các ký tự điều khiển thực hiện các hành động khác nhau trên các ký tự khác nhau. Có rất ít sự tiêu chuẩn giữa các thiết bị ra. Để tìm một cách chính xác cách mà một ký tự điều khiển ảnh hưởng lên các thiết bị cụ thể, bạn sẽ cần tài liệu hường dẫn cho nó.

Nhóm 32 ký tự mã ACII thứ hai được so sánh với các hệ thống dấu chấm câu khác nhau, các ký tự đặc biệt, và các chữ số. Các ký tự đáng chú ý nhất trong nhóm này bao gồm ký tự trống (mã ASCII 20h) và các chữ số (mã ASCII 30h..39h). Chú ý rằng các chữ số này khác với giá trị số của chúng chỉ trong nibble H.O. Bằng cách trừ 30h từ mã ASCII cho chữ số cụ thể nào đó bạn có thể thu được số tương đương với chữ số đó.

Nhóm 32 ký tự mã ASCII thứ ba được dành cho các ký tự chữ cái hoa. Các mã ASCII này là “A..Z” nằm trong khoảng 41h..5Ah (65..90). VÌ chỉ có 26 chữ cái khác nhau, 6 mã còn lại là dùng cho các ký tự đặc biệt.

Nhóm thứ bốn, và cũng là cuối cùng, nhóm 32 ký tự mã ASCII này được dùng cho các ký tự chữ cái thường, 5 ký tự đặc biết được thêm vào, và một ký tự điều khiển khác (delete). Chú ý rằng các ký tự chữ cái thường sử mã ASCII từ 61h..7Ah. Nếu bạn muốn chuyển các mã giữ các ký tự hoa và thường theo nhị phân, bạn sẽ cần lưu ý các ký tự hoa khác với các ký tự thường của chúng chỉ đúng một vị trí bit. Ví dụ như, xét các mã ký tự “E” và “e” sau đây:




Chỉ có một ví trí khác nhau của hai mã đó là bit năm. Ký tự hoa luôn chứa không ở bit năm; ký tự chữ cái thường luôn chứa một ở bit 5. Bạn có thể sử dụng đặc điểm này để chuyển đổi một cách nhanh chóng giữa ký tự hoa và ký tự thường. Nếu bạn có một ký tự hoa bạn có thể làm nó thành ký tự thường bằng cách đặt bit năm thành một. Nếu bạn có một ký tự thường và bạn muốn nó thành ký tự hoa , bạn có thể làm nó bằng cách đặt bit năm là không. Bạn có thể đảo ngược các ký tự chữ cái giữa ký tự hoa và thường một cách đơn giản là đảo ngược bit năm.

Quả thực, bit năm và sáu xác định được nhóm nào trong bốn nhóm của ký tự ASCII mà bạn đang dùng:




Vì vậy bạn có thể, ví dụ như, chuyển đổi giữa các ký tự hoa hay ký tự thường (hay các ký tự đặc biệt tương đương) thành các ký tự điều khiển tương đương với nó bằng cách đặt các bit năm và bit sáu thành không.

Xét các ký tự mã ASCII của các chữ số:




Các biểu diễn thập phân của các mã ASCII rất không sáng sủa. Tuy nhiên, biểu diễn của hexa của các mã ASCII này lại rất quan trọng , nibble L.O. của mã ASCII là số nhị phân tương đương với chữ số được biểu diễn. Bằng cách loại bỏ (ví dụ đặt bằng 0) nibble H.O. của một ký tự số, bạn có thể chuyển mã ký tự đó thành biểu diễn giá trị nhị phân tương đương. Ngược lại, bạn có thể chuyển một giá trị nhị phân trong phạm vi 0..9 thành biểu diễn ký tự ASCII của nó bằng cách đơn giản là đặt nibble H.O. thành ba. Chú ý rằng bạn có thể sử dụng các phép toán logic AND để làm cho các bit H.O. thành 0; cũng tương tự như vậy, bạn có thể sử phép logic OR để làm cho bit H.O. thành 0011(ba).

Chú ý rằng bạn không thể chuyển một chuỗi các ký tự số thành biểu diễn nhị phân tương đương của nó bằng cách loại bỏ đị nibble H.O. từ mỗi số trong chuỗi. Chuyển 123 (31h 32h 33h) trong dãy ba byte cấu thành: 010203h, không giá trị đúng là 7Bh. Chuyển một chuỗi chữ số thành một số nguyên đòi hỏi nhiều sự phức tạp hơn điều này; sự chuyển đổi trên chỉ làm việc cho mỗi chữ số duy nhất.

Bit bảy trong mã ASCII tiêu chuẩn luôn là không. Điều này nghĩa là tập ký tự ASCII chỉ dùng một nửa cho các mã trong 8 bit (1 byte). IBM sử dụng 128 ký tự còn lại cho các ký tự đặc biệt khác bao gồm ký tự quốc tế (ví dụ ký tự phát âm...), ký tự toán học, và các ký tự đường vẽ ( line drawing characters). Chú ý rằng không có một tiêu chuẩn mở rộng các ký tự cho bảng mã ASCII. Đương nhiên, hãng IBM có tầm ảnh hưởng rộng, vì vậy hầu hết tất cả các máy tính cá nhân hiện đại trên cơ sở 8086 với màn hình hiển thị được mở rộng ký tự IBM/ASCII. Đa số các máy in cũng hỗ trợ ký tự IBM.

Đoạn sau của phần này không quan trọng lắm nên tui cũng không post lên đây.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 31/01/2009 03:51:00 (+0700) | #11 | 167738
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Khi đọc chương này tui khuyên các bạn nên đọc kỹ bài "phép toán logic" ở chương trước và các bạn cũng nên có một it kiến thức về đại số boolean để dễ hiểu chương này hơn.

Chương 2:Hệ đại số boolean

Phần 2.1: Đại số boolean

Đại số boolean là một hệ thống toán học suy diễn logic được thực hiện trên các giá trị 0 và 1 (sai và đúng). Phép toán nhị phân “°” được định nghĩa trên tập các giá trị chấp nhận bởi một đôi giá trị boolean đầu vào và cho ra một giá trị boolean là kết quả. Ví dụ như, phép toán boolean AND chấp nhận 2 giá trị boolean đầu vào và cho ra một giá trị boolean đầu ra (phép logic AND cho hai đầu vào).

Đối với bất kỳ hệ thống đại số nào, cũng có một vài giả định ban đầu, hoặc quy tắc, đó là hệ thống sau. Bạn có thể suy ra các quy tắc, định lý, hay các thuộc tính khác của hệ từ hệ quy tắc cơ sở. Hệ đại số boolean thường dùng các quy tắc cơ sở sau:
-Tính kết thúc:

Hệ boolean được gọi là đóng lại với một phép toán nhị phân nếu cho mỗi đôi giá trị đầu vào, nó cho một giá trị boolean là kết quả. Ví dụ như, phép logic AND là đòng kín trong hệ boolean bởi vì nó chỉ chấp nhận các toán hạng boolean và chỉ cho ra một kết quả boolean.

- Tính giao hoán:

Một phép toán nhị phân “°” được gọi là kết hợp nếu A°B=B°A cho mỗi giá trị boolean A và B phù hợp.

- Tính kết hợp:

Một phép toán nhị phân “°” được gọi là kết hợp nếu (A ° B) ° C = A ° (B ° C) cho mỗi giá trị boolean phù hợp A, B, C

-Tính phân phối:

Hai phép toán nhị phân “°” và “%” được gọi là phân phối với nhau nếu: A °(B % C) = (A ° B) % (A ° C) cho mỗi giá trị boolean A, B, C.

-Tính đồng nhất:

Một giá trị boolean I được gọi là phần tử đồng nhất với một vài phép toán nhị phân “°”nếu: A ° I = A

-Tính nghịch đảo:

Một giá trị boolean I được gọi là phần tử nghịch đảo với một vài phép toán nhị phân “°” nếu: A°I = B và A≠B (B là phần tử bù với A trong hệ boolean).

Cho mục đích của chúng ta, chúng ta sẽ dựa trên cơ sở các tập hợp các toán tử và các giá trị sau:
- Hai giá trị phù hợp trong hệ boolean là 0 và 1. Chúng ta thường gọi chúng là sai (false) và đúng (true)

- Ký tự “•” biểu diễn phép toán logic AND; ví dụ A•B là phép logic AND của hai giá trị A và B. Khi sử dụng các chữ cái là tên biến, thì có thể không cần ký tự “•”; vì thế, AB cũng biểu diễn phép logic AND của hai biến A và B (chúng ta cũng gọi là tích của A và B).

- Ký tự “+” biểu diễn phép logic OR; ví dụ, A+B là phép OR cho hai giá trị boolean A và B (Chúng ta cũng gọi là tổng của A và B)

-Logic phần bù, sự phủ định, hay NOT, là phép toán một ngôi. Trong tài liệu này sẽ sử dụng ký hiệu (') để biểu thị phép logic phần bù. Ví dụ như, A' biểu thị logic NOT của A. Nếu một vài phép toán khác xuất hiện trong một biểu thức, kết quả của biểu thức phụ thuộc vào thứ bậc của các phép toán (dễ hiểu là nhân chia trước cộng trừ sau). Chúng ta sẽ sử dụng các thứ bậc sau (từ cao nhất đến thấp nhất) cho mỗi phép toán boolean: các dấu ngoặc đơn, logic NOT, logic AND, sau cùng là logic OR. Các phép toán logic AND và OR là (left associative) . Nếu hai phép toán logic cùng thứ bậc và kề với nhau, bạn phải thực hiện chúng từ trái qua phải. Logic NOT là (right associative); mặc dù nó cho ra cùng một giá trị khi sử dụng left hay right associativity vì nó là toán tử một ngôi.

Chúng ta sẽ sử dụng các quy tắc sau:

P1: Đại số boolean thực hiện chỉ dưới các toán tử AND, OR, NOT

P2: Phần tử đồng nhất cho • là 1 và + là 0. Không có phần tử đồng nhất cho phép toán NOT.

P3: • và + có tính giao hoán

P4: • và + có tính kết hợp đối với nhau. Đó là, A• (B+C)=(A• B)+(A• C) và A+(B• C)=(A+B)• (A+C).

P5: Cho mỗi giá trị A luôn tồn tại một giá trị A' sao cho A• A'=0 và A+A'=1. Giá trị này được gọi là giá trị bù (NOT) của A.

P6: • và + là các toán tử kết hợp. Đó là, (A• B)• C=A• (B• C) và (A+B)+C = A+(B+C)

.Chúng ta có thể chứng minh tất cả các định lý trong đại số boolean bằng cách sử dụng các quy địnht trên. Trong tài liệu này sẽ không đi vào cách chứng minh các định lý này, tuy nhiên, nó sẽ là điều rất tốt cho bạn với các định lý quan trọng này trong đại số boolean. Các ví dụ cho các định lý bao gồm:

Th1: A + A = A
Th2: A • A = A
Th3: A + 0 = A
Th4: A • 1 = A
Th5: A • 0 = 0
Th6: A + 1 = 1
Th7: (A + B)’ = A’ • B’
Th8: (A • B)’ = A’ + B’
Th9: A + A•B = A
Th10: A •(A + B) = A
Th11: A + A’B = A+B
Th12: A’ • (A + B’) = A’B’
Th13: AB + AB’ = A
Th14: (A’+B’) • (A’ + B) = A’
Th15: A + A’ = 1
Th16: A • A’ = 0

Định lý bảy và tám ở trên là định luật DeMorgan’s của toán học tên gọi của nó là của người khám phá ra định luật này.

Các định lý trên xuất hiện theo cặp. Mỗi cặp đôi (ví dụ Th1&Th2, Th3&Th4,...) là một dạng. Một yếu tố cơ bản quan trọng trong đại số boolean là tính đối ngẫu. Một biểu thức hợp lệ bạn có thể sử dụng các quy tắc và định lý của đại số boolean cũng là hợp lệ nếu bạn thay đổi các phép toán và hằng xuất hiện trong biểu thức . Đặc biệt, nếu bạn thay đổi các phép toán • và + và đổi giá trị 0 và 1 cho nhau trong biểu thức, bạn sẽ được một biểu thức cũng hợp lệ trong đại số boolean. Đây không phải là một đôi biểu thức cùng cho ra một giá trị, chỉ là một đôi biểu thức hợp lệ trong boolean. Vì vậy, đây là cách dễ dàng để tạo ra một định lý cho mỗi sự chứng minh của ban trong hệ đại số boolean

Mặc dù chúng ra sẽ không chúng minh các định lý cho mục địch của đại số boolean trong tài liệu này, chúng ta sẽ dử dụng chúng để tìm ra các biểu thức giống hệt nhau. Đây là phép toán quan trọng để tìm ra dạng biểu diễn chuẩn của biểu thức boolean hay khi đơn giản hóa biểu thức boolean
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 31/01/2009 22:02:41 (+0700) | #12 | 167761
[Avatar]
mystery_hacker
Member

[Minus]    0    [Plus]
Joined: 30/06/2006 16:16:03
Messages: 365
Location: Khánh Hòa
Offline
[Profile] [PM] [Yahoo!]
Cám ơn bác đã dịch cho mọi người đọc, nhưng nếu có thể, em muốn nhờ bác đóng thành ebook để tải về đọc cho tiện, đặc biệt là cho những người không có nhiều thời giờ online như em chẳng hạn.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 01/02/2009 12:41:01 (+0700) | #13 | 167803
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Làm ebook sẽ tốn rất nhiều thời gian mà tui cũng chẳng có nhiều thời gian như bạn vậy. Mấy bữa tết rãnh nên post được nhiều, sau tết có thể 3,4 có khi 1 tuần tui mới post một bài. Hihi thông cảm "Từ từ rồi khoai nó nhừ" smilie

Phần 2.2:Hàm boolean và bảng chân trị

Một biểu thức boolean là một dãy không, một, và các chữ (các biến) riêng biệt xây dựng từ các phép toán boolean. Một chữ có thể là một biến bị phủ định hay không. Cho mục đích của chúng ta, tất cả các tên biến sẽ là các chữ cái. Một hàm boolean là một biểu thức boolean đặc thù; chúng ta sẽ gọi chung các hàm boolean với tên là “F” với số phù hợp đánh ở dưới. Ví dụ như, xét hàm boolean sau:

F0=AB+C

Hàm này được thiết lập bởi phép logic AND của A và B và sau đó là logic OR của kết quả này với C. Nếu A=1, B=0, và C=1, thì F0 trả lại kết quả là 1 (1•0 + 1 = 1).

Một cách khác để biểu diễn hàm boolean là dùng bảng chân trị. Ở chương trước chúng ta đã sử dụng bảng chân trị để biểu diễn các hàm AND và OR. Bảng chân trị của các hàm này được đưa ra dưới dạng sau:
Logic AND:



Logic OR:




Với mỗi phép toán nhị phân và hai giá trị biến đầu vào, dạng của bảng chân trị được hình thành rất tự nhiên và phù hợp. Tuy nhiên, ta lại xét hàm F0 ở trên. Hàm này có ba biến, không hai. Vì vậy, không thể sử dụng dạng bảng chân trị như trên để biểu diễn. May thay, nó vẫn là con đường dễ dàng để đặt ra bảng chân trị cho các hàm 3 biến hoặc có nhiều biến hơn. Ví dụ sau đây sẽ minh họa cách làm một hàm ba hoặc bốn biến:

Bảng chân trị cho hàm ba biến:




Bảng chân trị cho hàm bốn biến:




Trong bảng chân trị nói trên, bốn cột biểu diễn bốn tổ hợp của không và một cho A&B (B là bit H.O. là bit đầu tiên bên trái, A là bit L.O. là bit cuối cùng bên phải). Cũng tương tự như vậy bốn dòng của bảng chân trị thứ hai trên biểu diễn các tổ hợp phù hợp cho của không và một cho các biến C và D. Cũng như thế, D là bit H.O. và C là bit L.O.

Bảng tiếp theo sau đây là một cách khác để biểu diễn bảng chân trị. Đây là dạng có hai điều thuận lợi hơn hai dạng trên - nó dễ dàng hơn để điền vào bảng và nó một biểu diễn ngắn gọn của hai hay nhiều hàm:




Chú ý bảng chân trị này cho ra các giá trị của ba hàm boolean ba biến riêng biệt.

Mặc dù bạn có thể tạo ra vô hàm các hàm boolean, chúng không là duy nhất. Ví dụ như, F=A và F=AA là hai hàm khác nhau. Nhưng bằng định lý hai, tuy nhiên, chúng ta dễ thấy chúng tương đương với nhau, đó là, chúng cùng cho ra một giá trị cho tất cả các tổ hợp đầu vào. Nếu bạn quy định số các biến cho hàm boolean, thì chỉ có giới hạn một số lượng các hàm này. Ví dụ như, chỉ có 4 hàm cho một biến (đó là A; A'; A+A'; A • A'), chỉ có 16 hàm duy nhất cho hai biến và có 256 hàm phù hợp cho 3 biến. Cho n biến, thì có 2^(2^n) các hàm boolean cho n biến giá trị đặt vào.Áp dụng công thức này ta có với 2 biến, có 2^(2^2)=2^4 hay 16 hàm khác nhau. Với ba biến có 2^(2^3)=256 hàm phù hợp. Với bốn bit có thể tạo được 2^(2^4)=2^16 hay 65,536 hàm khác nhau.

Khi làm việc với chỉ với 16 hàm 2 biến, chúng ta có thể dễ dàng gọi tên đầy đủ cho mỗi hàng. Bảng liệt kê 16 hàm 2 biến sau đây với các tên thông dụng cho mỗi hàm:




Khi có nhiều hơn 2 biến sẽ có quá nhiều hàm để có thể đặt cho chúng một cái tên. Vì thế, chúng ta sẽ gọi tên các hàm bằng cách dùng số thứ tự hàm hơn là dùng tên. Ví dụ như F8 biểu thị logic AND của A và B và F14 là phép logic OR. Đương nhiên, có một vấn đề là xác định số thứ tự hàm. Ví dụ như, cho hàm ba biến F=AB+C, số nào tương đương với hàm này? Rất dễ để tính được nó bằng cách nhìn vào bảng chân trị cho hàm này. Nếu chúng ta coi các giá trị A, B, C như là các bit trong một số nhị phân với C là bit H.O. và A là bit L.O, chúng cho các kết quả là các số nhị phân từ không đến bảy. Nếu chúng ta làm ra một giá trị nhị phân bằng cách đặt các kết quả có thể của hàm trong vị trí bit được định bởi A, B, và C, kết quả của số nhị phân này chính là số thứ tự hàm. Xét bảng chân trị cho hàm F=AB+C ta có:




Nếu chúng ta coi các giá trị của F như là một số nhị phân, điều này sẽ cho chúng ta giá trị F8(số hexa) hay 24810 là số thứ tự hàm. Chúng ta thường định các số thứ tự hàm trong hệ thập phân

Để làm hiểu rõ vì sao có 2^(2^n) hàm khác nhau của n biến chúng ta dùng cách tìm số thứ tự hàm trên và phép đếm: Nếu bạn có n biến, có 2^n bit trong số thứ tự hàm. Nếu bạn có m bit, sẽ có 2^m các giá trị khác nhau. Vì vậy, với n biến sẽ có m=2^n bit phù hợp và có 2^m hay 2^(2^n) hàm phù hợp.

Sorry vì cái bảng tiếng anh. Nhưng cũng chẳng còn cách nào vì chằng biết vẽ bảng ở trong diễn đàn như thế nào, bác nào biết có thể bày tui với (tui có biết về Javascript). Thanks smilie
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 02/02/2009 10:07:36 (+0700) | #14 | 167859
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Hết tết rùi buồn wa' smilie

Phần 2.3: Thực hiện tính các biểu thức boolean

Bạn có thể chuyển một dạng biểu thức boolean thành một biểu thức tương đương bằng cách áp dụng các quy tắc định lý của đại số boolean. Đây là điều quan trọng nếu bạn muốn chuyển một biểu thức thành dạng chuẩn (a standardized form) hay bạn muốn giảm bớt số lượng các chữ (không phủ định hoặc bị phủ định) hoặc các hạng trong một biểu thức. Rút gọn các hạng và biểu thức có thể rất quan trọng bởi vì các mạch điện tử là gồm các thành phần riêng biệt thực hiện mỗi hạng hoặc các chữ trong biểu thức. Rút gọn biểu thức cho phép nhà thiết kế sử dụng ít hơn các thành phần mạch điện và, vì vậy, có thể giảm thiều giá thành hệ thống.

Không may, không có một quy tắc được quy định mà bạn có thể áp dụng để tối ưu biểu thức. Giống như sự xây dựng các chứng minh toán học, khả năng để có thể thực hiện công việc chuyển đổi một cách dễ dàng là dựa vào kinh nghiệm. Tuy thế, một vài ví dụ có thể thực hiện dễ dàng bằng các quy định:

ab + ab’ + a’b = a(b+b’) + a’b ( P4)
= a•1 + a’b (P5)
= a + a’b (Th4)
= a + a’b + 0 (Th3)
= a + a’b + aa’ (P5)
= a + b(a + a’) (P4)
= a + b•1 (P5)
= a + b (Th4)
(a’b + a’b’ + b’)‘ = ( a’(b+b’) + b’)’ (P4)
= (a’ + b’)’ (P5)
= ( (ab)’ )’ (Th8)
= ab Định nghĩa của not
b(a+c) + ab’ + bc’ + c = ba + bc + ab’ + bc’ + c (P4)
= a(b+b’) + b(c + c’) + c (P4)
= a•1 + b•1 + c (P5)
= a + b + c (Th4)

Mặc dù tất cả các ví dụ này sử dụng các biển đổi đại số để đơn giản hóa một biểu thức boolean, chúng ta cũng có thể sử dụng các phép toán đại số cho các mục đích khác. Ví dụ như, phần kế tiếp miêu tả dạng chuẩn của biểu thức boolean. Dạng chuẩn hiếm khi là dạng tối ưu.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 06/02/2009 05:57:57 (+0700) | #15 | 168360
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Bài này khá dài nên các bạn nên đọc một cách kỹ lưỡng

Phần 2.4: Dạng chính tắc

Vì chỉ có một lượng có hạn số lượng các hàm của n bit, tất nhiên là có vô hạn số các biểu thức logic phù hợp bạn có thể đặt ra với n giá trị đầu vào, cố nhiên là có vô hạn các biểu thức logic như nhau (cùng cho ra một giá trị với cùng đầu vào). Để loại đi sự nhầm lẫn, các nhà thiết kế logic thường chỉ rõ một hàm logic sử dụng dạng chính tắc, hay dạng tiêu chuẩn. Cho một hàm boolean luôn tồn tại một dạng chính tắc. Điều này sẽ loại trừ một vài sự rắc rối khi xử lý các hàm boolean. Sử dụng nguyên lý đối ngẫu, chúng ta dễ dàng chuyển đổi giữa hai dạng này.

Một hạng là một biến hay là một tích của (logic AND) của một vài chữ. Ví dụ như, nếu bạn có hai biến, A và B, có 8 hạng phù hợp: A, B, A', B', A'B', A'B, AB', và AB. Cho 3 biến chúng ta có 26 hạng khác nhau: A, B, C, A’, B’, C’, A’B’, A’B, AB’, AB, A’C’, A’C, AC’, AC, B’C’, B’C, BC’, BC, A’B’C’, AB’C’, A’BC’, ABC’, A’B’C, AB’C, A’BC, ABC. Như bạn thấy, khi số lượng các biến tăng, số lượng các hạng gia tăng một cách nhanh chóng. Một tiểu hạng là tích của n chữ cái. Ví dụ như, các hạng cho hai biến là: A’B’, AB’, A’B, và AB. Tương tự như vây, các tiểu hạng cho ba biến A, B và C là A’B’C’, AB’C’, A’BC’, ABC’, A’B’C, AB’C, A’BC, và ABC. Tổng quát, có 2^n tiểu hạng cho n biến. Các tiểu hạng rất dễ dàng để tạo ra bởi vì chúng tương đương với các số nhị phân khác nhau:

Bảng nhị phân của các tiểu hạng cho ba biến:




Chúng ta có thể chỉ rõ một vài hàm boolean tương đương với tổng (logic OR) các tiểu hạng. Cho hàm F248= AB+C tương đương với dạng chính tắc là ABC+A’BC+AB’C+A’B’C+ABC’. Bằng đại số, chúng ta có thể biểu diễn hai biểu thức này tương đương như sau:

ABC+A’BC+AB’C+A’B’C+ABC’
= BC(A+A’) + B’C(A+A’) + ABC’
= BC•1 +B’C•1 + ABC’
= C(B+B’) + ABC’
= C + ABC’
= C + AB

Có thể thấy được dạng chính tắc không phải là dạng tối ưu. Trên một phương diện khác, có một sự thuận lợi lớn cho dạng chính tắc là tổng các tiểu hạng: rất dễ dàng để tạo ra bảng chân trị cho một hàm từ dạng chính tắc của nó. Hơn nữa, cũng dễ dàng để tạo ra các phương trình logic từ bảng chân trị

Để xây dựng bảng chân trị từ dạng chính tắc, một cách đơn giản là chuyển mỗi tiểu hạng vào trong một giá trị nhị phân bằng cách gán “1” cho những biến bị phủ định và “0” cho những biến còn lại.

Sau đó đặt 1 ở vị trí tương đương (được xác định bởi giá trị nhị phân tiểu hạng) trong bảng chân trị

1) Chuyển các tiểu hạng thành giá trị nhị phân tương đương:

F248
= CBA + CBA’ + CB’A + CB’A’ + C’BA
= 111 + 110 + 101 + 100 + 011

2) Đặt 1 trong bảng chân trị cho các giá trị trên

Bước 1:




Cuối cùng, đặt không vào trong các ô còn lại mà bạn chưa điền ở bước 1

Bước 2:




Bây giờ chúng ta sẽ tạo ra hàm logic từ một bảng chân trị, nó cũng khá dễ dàng. Đầu tiên, xác định tất cả những vị trí của hàm logic có giá trị là 1. Trong bảng trên, có 5 giá trị như thế trong bảng trên. Số lượng của những ô chứa 1 xác định số lượng các tiểu hạng trong phương trình chính tắc. Để tạo ra các tiểu hạng, ta coi A, B, C cho giá trị 1 và A', B', hay C' cho giá trị 0 trong bảng chân trị ở trên. Sau đó lấy tổng các tiểu hạng đó chúng ta được kết quả. Trong ví dụ trên, F248 chứa 1 cho các giá trị của CBA=111, 110, 101, 100 và 011. Vì vậy, F248 = CBA + CBA’ + CB’A + CB’A’ + C’AB. Hạng đầu tiên, CBA, được lấy từ phần tử cuối của bảng trên. C, B, và A tất cả đều chứa 1 nên chúng ta tao ra một tiểu hạng là CBA (hoặc ABC, nếu bạn thích). Hạng thứ hai chứa giá trị 110 cho CBA, vì vậy chúng ta tạo ra tiểu hạng tiếp theo là CBA'. Tương tự, 101 cho CB'A; 100 cho CB'A', và 011 cho C'BA. Đương nhiên, các phép toán logic OR và AND là có tính chất hoán vị, vì vậy chúng ta có thể sắp xếp các hạng trong các tiểu hạng như chúng ta muốn và chúng ta có thể sắp xếp các tiểu hạng trong tổng theo ý thích. Quá trình này thực hiện tương tự cho bất kỳ số lượng các biến. Xét hàm F53504 = ABCD + A’BCD + A’B’CD + A’B’C’D. Đặt 1 vào các vị trí thích hợp trong bảng chân trị như sau:




Tất cả các phần tử còn lại trong bảng chân trị đều chứa không.

Có lẽ cách dễ nhất để tạo ra dạng chính tắc của hàm boolean đầu tiên là tạo bảng chân trị cho hàm và sau đó xây dựng dạng chính tắc từ bảng chân trị. Chúng ta sẽ sử dụng phương pháp này, ví dụ như, khi chuyển đổi giữa hai dạng chính tắc được nói tới trong phần này. Tuy nhiên, nó cũng là vấn đề đơn giản để tạo ra tổng các tiểu hạng bằng đại số. Bằng cách sử dụng luật phân phối và định lý 15 (A+A'=1) làm công việc này dễ dàng hơn. Xét F248=AB+C. Đây là hàm chứa hai hạng, AB và C, nhưng chúng không phải là các tiểu hạng. Các tiểu hạng chứa các biến phù hợp ở trong các dạng phủ định hay không phủ định. Chúng ta có thể chuyển hạng đầu tiên thành tổng các tiểu hạng như sau:

AB = AB • 1 (Th4)
= AB • (C + C’) (Th 15)
= ABC + ABC’ Luật phân phối
= CBA + C’BA Luật phân phối

Tương tự, chúng ta có thể chuyển đổi hạng thứ hai trong F248 thành tổng các tiểu hạng như sau:

C = C • 1 (Th4)
= C • (A + A’) (Th15)
= CA + CA’ Luật phân phối
= CA•1 + CA’•1 (Th4)
= CA • (B + B’) + CA’ • (B + B’) (Th15)
= CAB + CAB’ + CA’B + CA’B’ Luật phân phối
= CBA + CBA’ + CB’A + CB’A’ Luật hoán vị
Bước cuối cùng (sắp xếp lại các biến) trong hai chuyển đổi là tùy ý. Để thu được dạng cuối cùng của F248 chúng ta chỉ cần lấy tổng các kết quả từ hai sự chuyển đổi:

F248 = (CBA + C’BA) + (CBA + CBA’ + CB’A + CB’A’)
= CBA + CBA’ + CB’A + CB’A’ + C’BA

Một con đường khác để tạo ra dạng chính tắc là sử dụng tích các đại hạng. Một đại hạng là tổng (logic OR) của tất cả các biến, bị phủ định hoặc không. Ví dụ như, xét hàm logic G ba biến sau:

G = (A+B+C) • (A’+B+C) • (A+B’+C).

Như dạng tổng tiểu hạng, có đúng một tích các đại hạng cho mỗi hàm logic. Đương nhiên, cho mỗi tích các đại hạng có một dạng tổng các tiểu hạng tương đương. Ở đây, hàm G là tương đương với

F248 = CBA + CBA’ + CB’A + CB’A’ + C’BA = AB +C.

Tạo một bảng chân trị từ tích các đại hạng cũng không khó khăn hơn khi xây dựng nó từ tổng các tiểu hạng. Bạn sử dụng nguyên lý đối ngẫu để làm điều này. Nhớ rằng, nguyên lý đối ngẫu là chuyển đổi AND thành OR và không thành một (và ngược lại). Vì vậy, để xây dựng bảng chân trị, đầu tiên bạn cần đổi các chữ phủ định và không bị phủ định cho nhau.

Ở hàm G trên, thì đây là:

G= (A’ + B’ + C’) • (A + B’ + C’) • (A’ + B + C’)

Bước tiếp theo là đổi các phép toán logic OR và AND. Điều này cho ta

G = A’B’C’ + AB’C’ + A’BC’

Cuối cùng, bạn cần đổi tất cả các số không và một cho nhau. Điều này nghĩa bạn cho không vào bảng chân trị cho mỗi tiểu hạng ở trên và sau đó điền vào phần còn lại bảng chân trị là một. Cụ thể là đặt không vào các vị trí 0,1,2 trong bảng chân trị. Điền những ô còn lại là một ta có bảng chân trị của F248

Bạn có thể dễ dàng chuyển đổi giữa hai dạng chính tắc bằng cách tạo bảng chân trị cho một dạng và thực hiện quay lui từ bảng chân trị để làm ra dạng còn lại. Ví dụ như, xét hàm hai biến, F7= A+B. Tổng các tiểu hạng có dạng là F7=A'B+AB'+AB. Bảng chân trị như sau:




Làm việc quay lui để được tích các đại hạng, chúng ta xác định tất cả các vị trí có kết quả là 0. Đây là phần tử mà đầu vào A và B đều bằng 0 (hình trên bảng có sai một tý). Vậy bước đầu chúng ta có G=A'B'. Tuy nhiên, chúng ta vẫn cần đảo ngược tất cả các biến để thu được G=AB. Bằng nguyên lý đối ngẫu chúng ta cần đổi giữa logic OR và AND thu được G=A+B. Đây là dạng chính tắc của các đại hạng

Vì làm việc với tích các đại hạng có ít sự rắc rối hơn là làm việc với tổng các tiểu hạng, nhưng tài liệu này thường sử dụng dạng tổng tiểu hạng. Hơn nữa, tổng các tiểu hạng thông dụng hơn trong logic boolean. Tuy nhiên, bạn cần phải học cả hai dạng này khi thiết kế logic
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 09/02/2009 02:34:09 (+0700) | #16 | 168742
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Cũng như phần trên các bạn nên đọc kỹ để hiểu phần này. Thân! smilie

Phần 2.5: Cực tiểu hóa các hàm boolean

Vì có một số lượng vô hạn các hàm boolean n biến, nhưng chỉ có một lượng có hạn số các hàm boolean đơn nhất cho n biến đó, bạn tự hỏi có hay không một phương pháp dùng để đơn giản hóa một hàm boolean thành dạng tối ưu. Tất nhiên, bạn luôn có thể sử dụng các biến đổi đại số để làm ra dạng tối ưu, nhưng sử dụng cách như vậy không thể đảm bảo rằng đó là dạng tối ưu. Do đó, tuy nhiên, có hai phương pháp sẽ đơn giản hàm boolean đưa nó về dạng tối ưu: phương pháp bản đồ và phương pháp lập bảng ứng viên. Trong tài liệu này chúng ta chỉ dùng phương pháp bản đồ, xem các tài liệu về thiết kế logic cho các phương pháp khác.

Mỗi hàm logic thì luôn có một vài dạng tối ưu phải tồn tại, bạn có lẽ sẽ hỏi rằng tại sao chúng ta không sử dụng dạng tối ưu làm dạng chính tắc. Có hai lý do. Đầu tiên, có một vài dạng tối ưu. Chúng không chắc chắn là duy nhất. Thứ hai, dạng chính tắc rất dễ dàng để chuyển đổi giữa nó và dạng bảng chân trị (dạng tối ưu không như vậy). Cho một hàm nhiều hơn sáu biến, cố gắng sử dụng phương pháp bản đồ để đơn giản nó bằng tay thì không phải là điều thông minh.

Bước đầu tiên để sử dụng phương pháp bản đồ là xây dựng một bảng chân trị 2 chiều cho hàm :




Chú ý: Hãy nhìn một cách cẩn thận vào bảng chân trị. Chúng không cùng dạng với dạng đã xuất hiện trong phần trước. Điểm khác biệt, chuỗi giá trị của dạng này là 00,01, 11, 10, không là 00, 01, 10, 11. Đây là điều rất quan trọng! Nếu bạn cấu tạo bảng chân trị theo một chuỗi nhị phân liên tục, phương pháp tối ưu bản đồ sẽ làm việc không chính xác. Chúng ta sẽ gọi bảng chân trị dạng này là bản đồ chân trị để phân biệt với dạng bảng chân trị tiêu chuẩn của nó.

Giả sử hàm boolean của bạn là dạng chính tắc (tổng các tiểu hạng), đặt 1 cho mỗi vị trí trong bản đồ chân trị cho mỗi tiểu hạng trong hàm. Đặt không cho các vị trí còn lạ. Ví dụ như, xét hàm ba biến F= C’B’A + C’BA’ + C’BA + CB’A’ + CB’A + CBA’ + CBA. Hình sau đây biểu diễn bản đồ chân trị cho hàm này.:




Bước kế tiếp là vẽ các hình chữ nhật bao quanh các nhóm số 1 chữ nhật. Mỗi hình chữ nhật mà bạn vẽ phải có diện tích là lũy thừa của 2. Các hàm ba biến, thì các hình chữ nhật phải có các diện tích là 1, 2, và 4. Tập hợp các hình chữ nhật mà bạn vẽ phải bao quanh tất cả nhưng ô chứa 1 trong bản đồ chân trị. Thủ thuật là vẽ tất cả hình chữ nhật phù hợp trừ phi một hình chữ nhật hoàn toàn bị bao lại trong các cái khác. Chú ý các hình chữ nhật có thể trùng lên nhau nếu một cái không bị bao bởi các cái khác. Trong bản đồ chân trị của hàm F có các hình chữ nhật như sau:




Mỗi hình chữ nhật biểu diễn cho một hạng trong hàm được đơn giản. Vì vậy, hàm cực tiểu sẽ chỉ chứa ba hạng. Bạn xây dựng mỗi hạng sử dụng quá trình loại bỏ. Bạn loại bỏ các biến vừa có các dạng phủ đinh và không phủ định xuất hiện trong hình chữ nhật. Xét hình chữ nhật gầy nhất ở trên ở đó trong hàng này C=1. Hình chữ nhật này chữa các biến A và B ở cả hai dạng phủ định và không phủ định. Vì vậy, chúng ta có thể loại bỏ đi các hạng A và B. Vì hình chữ nhật nằm trong vùng có C=1, nên hình chữ nhật này sẽ biểu diễn một chữ là C.

Bây giờ xét hình vuông tô đậm ở trên. Hình chữ nhật này bao gồm C, C', B, B' và A. Vì vậy, nó biểu diễn một hạng đơn là A. Tương tự, hình vuông với đường kẻ mờ ở trên chứa C, C', A, A' và B. Vì vậy, nó biểu diễn một hạng đơn là B.

Cuối cùng, dạng tối ưu của hàm là tổng (logic OR) của các hạng được biểu diễn bằng ba hình chữ nhật. Vì vậy, F = A + B + C. Bạn không cần phải quan tâm đến các hình vuông chứa số không.

Khi bạn nhóm các nhóm số 1 trong bản đồ chân trị, bạn phải xét tới các dạng đường bao quanh của bản đồ chân trị (ví dụ như hình cái bánh rán). Lề bên phải của bản đồ bọc quanh lề bên trái của bản đồ (và ngược lại). Tương tự, đỉnh đầu phải bọc quanh với đỉnh cuối. Điều này sẽ cho thêm nhiều sự phù hợp khi nhóm các nhóm số một trong bản đồ. Xét hàm boolean F=C’B’A’ + C’BA’ + CB’A’ + CBA’. Hình dưới đây biểu diễn bản đồ chân trị của hàm này:




Khi nhìn thoáng qua, bạn sẽ nghĩ rằng có hai hình chữ nhật phù hợp như trong hình dưới đây:




Tuy nhiên, bởi vì bản đồ chân trị là đối tượng liên tục nhau với cạnh bên phải và cạnh bên trai được nối tiếp, nên chúng ta có thể làm ra một dạng đơn giản, hình chữ nhật vuông, như hình sau:




Điều này là gì? Tại sao chúng ta phải cẩn thận nếu chúng ta có một hình chữ nhật hay hai trong bản đồ chân trị? Câu trả lời là vì có nhiều hình chữ nhật hơn, sẽ có nhiều hạng hơn trong biểu thức cuối. Có ít hình chữ nhật hơn, sẽ ít hạng xuất hiện hơn trong hàm boolean cuối cùng. Ví dụ như, ví dụ đang xét với hai hình chữ nhật sẽ tạo ra hai hạng. Hình chữ nhật đầu tiên (bên trái) loại đi biến C, để lại A'B'. Hình chữ nhật thứ hai, bên trái, cũng loại đi biến C, để lại BA'. Vì vậy, bản đồ chân trị sẽ cho ra phương trình F= A’B’ + A’B. Chúng ta biết nó không là dạng tối ưu, xem định lý 13. Bây giờ xét bản đồ chân trị thứ hai ở trên. Ở đây chúng ta có một hình chữ nhật vì vậy hàm boolean sẽ chỉ có đúng một hạng. Có thể thấy được đây là dạng tối ưu hơn là dạng với hai hạng. Vì hình chữ nhật này bao gồm C và C' và B và B', chỉ để lại duy nhất một hạng là A'. Hàm boolean này, vì vậy, rút gọn thành F=A'.

Có hai trường hợp mà phương pháp bản đồ chân trị không thể xử lý đúng là : một bản đồ chân trị chứa tất cả không hoặc bản đồ chân trị chứa tất cả một. Hai trường hợp này lần lượt tương đương với hai hàm boolean F=0 và F=1. Các hàm này có thể dễ dàng nhận ra bằng cách xem xét bản đồ chân trị.

Một điều quan trong bạn phải ghi nhớ khi tối ưu các hàm boolean sử dụng phương pháp bản đồ chân trị là bạn luôn luôn phải chọn lọc các hình chữ nhật có diện tích khã dỉ lớn nhất là lũy thừa của 2. Bạn phải làm việc này ngay cả khi các hình chữ nhật trồng lên nhau (trừ phi một hình chữ nhật nào đó bị phủ hết bởi các hình khác). Xét hàm F = C'B'A' + C'BA' + CB'A' + C'AB + CBA' + CBA. Bản đồ chân trị của hàm này ở hình sau:




Ban đầu khi chưa xem xét kỷ lưỡng thì có thể tạo ra tập các hình chữ nhật như sau:




Tuy nhiên hình đúng là bản đồ ở hình sau:




Tất cả ba bản đồ đều sẽ cho ra hàm boolean với hai hạng. Tuy nhiên, các dạng đầu tiên sẽ cho ra biểu thức F=B + A'B' và F=AB+A'. Dạng thứ ba cho ra F=B+A'. Có thể thấy được, dạng cuối cùng tối ưu hơn các hai dạng khác (định lý 11 và 12).

Với một hàm ba biến, kích thước của hình chữ nhất xác định số hạng mà nó biểu diễn :

•Một hình chữ nhật bao quanh một vuông chứa 1 biểu diễn một tiểu hạng. Các hạng kết hợp sẽ có ba chữ.


•Một hình chữ nhật bao quanh hai ô vuông chứa một biểu diễn một hạng chứa hai chữ.

•Một hình chữ nhật bao quanh bốn ô vuông chứa 1 biểu diễn một hạng chứa một chữ.

• Một hình chữ nhật bao quanh tám hình vuông biểu diễn hàm F=1.

Bản đồ chân trị bạn tạo ra cho bốn biến khá phức tạp. Đây là vì có rất nhiều nơi hình chữ nhật có thể ẩn đi khi bạn đi dọc theo các cạnh. Hình sau đây cho biết một vài vị trí mà các hình chữ nhật phù hợp có thể ẩn đi:




Mẫu hình liệt kê này không phải là tất cả chúng! Ví dụ như, biểu đồ này chưa có các hình chữ nhật 1x2. Bạn phải rèn luyện cẩn thận khi làm việc với bản đồ 4 biến để chắc chắn rằng bạn chọn đúng các hình chữ nhật phù hợp lớn nhất, đặc biệt khi sự phủ hình xảy ra. Đây là điều đặc biệt quan trọng với bạn để có hình chữ nhật bên một cạnh của bản đồ chân trị.

Như các hàm ba biến, kích thước hình chữ nhật trong bản đồ chân trị bốn biến quyết định số lượng các hạng mà nó biểu diễn:

• Một hình chữ nhật bọc một ô vuông biểu diễn một tiểu hạng. Các hạng kết hợp có bốn chữ.

•Một hình chữ nhật bao quanh hai ô vuông chứa một biểu diễn một hạng chứa ba chữ.

•Một hình chữ nhật bao quanh bốn ô vuông chứa một biểu diễn một hạng chứa hai chữ.

•Một hình chữ nhật bao quanh tám ô vuông chứa một biểu diễn một hạng chứa đúng một chữ.

•Một hình chữ nhật bao quanh mười sáu ô vuông chứa một biểu diễn hàm F=1.

Đây là ví dụ cuối cùng thể hiện cách tối ưu của hàm bốn biến. Hàm được cho là F = D’C’B’A’ + D’C’B’A + D’C’BA + D’C’BA’ + D’CB’A + D’CBA + DCB’A + DCBA + DC’B’A’ + DC’BA’, bản đồ chân trị của nó như sau:




Có hai tập các hình chữ nhật lớn nhất cho hàm này, mỗi cái cho ba hạng:




Các hàm cho ra là tương đương nhau, chúng tối ưu như nhau (dạng tối ưu không duy nhất). Cả hai đều có thể dùng cho mục đích của chúng ta.

Đầu tiên, hãy xét hạng được biểu diễn bởi hình chữ nhật tạo thành bởi bốn góc. Hình chữ nhật này chứa B, B', D, và D'; vì vậy chúng ta có thể loại bỏ các hạng này. Hạng còn lại chứa ở trong hình chữ nhật là C' và A', vì vậy hình chữ nhật này biểu diễn hạng C'A'

Hình chữ nhật thứ hai, đều có cả ở hai bản đồ, là hình chữ nhật tạo bởi bốn ô vuông ở giữa. Hình chữ nhật này bao gồm các hạng A, B, B', C, D, và D'. Loại bỏ B, B', D và D', chúng ta thu được CA là hạng của hình chữ nhật này.

Bản đồ bên trái có hạng thứ ba được biểu diễn bằng dòng đầu tiên. Đây là hạng bao gồm các biến A, A, B, B', C' và D'. Vì nó chứa A, A', B và B', chúng ta có thể loại bỏ các hạng này. Để lại hạng C'D'. Vì vậy, hàm biểu diễn bởi bản đồ này là F=C’A’ + CA + C’D’.

Bản đồ bên phải có hạng thứ ba được biểu diễn bằng bốn ô vuông đầu/giữa. Đó là hình chữ nhật gồm các biến A, B, B', C, C' và D'. Chúng ta có thể loại bỏ B, B', C và C' vì chúng là các dạng phủ định và không phủ định, để lại hạng AD. Vì vậy, hàm biểu diễn bởi bản đồ bên phải là F=C’A’ + CA +AD’.
Vì cả hai biểu thức là tương đương, chứa cùng số hạng, và cùng số phép toán. Trừ khi có một lý do khác bắt buộc chúng ta phải chọn một trong hai dạng, còn không bạn có thể sử dụng cả hai.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 09/02/2009 11:00:36 (+0700) | #17 | 168786
[Avatar]
Pmaldini2101
Member

[Minus]    0    [Plus]
Joined: 07/02/2009 00:13:19
Messages: 2
Location: Ha Noi
Offline
[Profile] [PM] [Email] [Yahoo!]
Rất cám on bạn mình cũng đang cần tìm những tài liệu này tuy nhiên tiếng anh thì không hiểu lắm cứ tiếng việt mới hiểu
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 10/02/2009 08:51:25 (+0700) | #18 | 168894
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Cảm ơn bác Pmaldini2101 đã ủng hộ. Tui sẽ cố gắng phát huy smilie

Khi "nuốt" được các phần trên các thì các bạn dễ dàng hiểu được các phần sau của chương này

Phần 2.6.1: Sự tương đương giữa mạch điện tử và hàm boolean

Có một sự tương ứng một-một giữa các mạch điện tử và hàm boolean. Với mỗi hàm boolean bạn có thể thiết kế một mạch điện tử và ngược lại. Vì hàm boolean chỉ yêu cầu các toán tử AND, OR, và NOT, chúng ta có thể đặt ra các mạch điện tử sử dụng các phép toán này, Hàm boolean AND, OR, và NOT tương đương với các mạch điện tử sau, gọi là cổng AND, OR và cổng đảo ngược (NOT).




Một điều thú vị là bạn chỉ cần một loại cổng để thực hiện được tất cả các mạch điện tử. Đây là cổng NAND trong hình sau:




Để chứng minh chúng ta có thể đặt ra các hàm boolean cở sở sử dụng cổng NAND, chúng ta chỉ cần chỉ ra các xây dựng các cổng NOT, cổng AND, và cổng OR từ cổng NAND (vì chúng ta có thể tạo ra tất cả các hàm boolean chỉ sử dụng AND, OR, và NOT). Xây dựng cổng NOT khá dễ, chỉ cần cho hai đầu vào là như nhau:




Chúng ta đã tạo được cổng NOT, thì xây dựng cổng AND trở nên dễ dàng – chỉ cần đảo ngược đầu vào của cổng NAND. Sau tất cả, NOT (NOT (A AND B)) là tương đương với A AND B. Đương nhiên, phải dùng hai cổng NAND để tạo ra một cổng AND, không một ai nói rằng mạch được đặt ra chỉ với cổng NAND là tốt nhất, chỉ là nó có thể phù hợp làm điều đó




Cổng cuối cùng chúng ta cần tạo là cổng logic OR. Chúng ta có thể dễ dàng đặt ra cổng OR từ cổng NAND bằng luật DeMorgan’s.

(A or B)’ = A’ and B’ Luật DeMorgan’s .
A or B = (A’ and B’)’ Đảo ngược cả phương trình.
A or B = A’ nand B’ Định nghĩa phép toán NAND.

Bằng cách áp dùng các chuyển đổi này, bạn được mạch như sau:




Bây giờ bạn có lẽ bạn tự hỏi tại sao chúng ta lại phiền lòng với điều này. Đó là, tại sao không chỉ dùng các cổng AND, OR, và NOT? Có hai lý do cho điều này. Đầu tiên, sử dụng cổng NAND để xây dựng các mạch thông thường ít đắt hơn các cổng khác. Thứ hai, nó cũng dễ dàng hơn để xây dựng các mạch phức hợp từ các khối xây dựng cơ sở hơn là xây dựng các mạch phức hợp sử dụng các cổng cơ sở khác.

Chú ý, cũng bằng cách này, cũng có thể đặt ra các mạch logic sử dụng cổng NOR (NOT(OR)). Sự tương đương giữa logic NAND và NOR là sự trực giao tương đương giữa hai dạng chính tắc được nói tới trong chương này (tổng các tiểu hạng vs, tích các đại hạng). NOR rất hữu dụng với nhiều mạch, nhưng hầu hết các nhà thiết kế mạch điện tử sử dụng logic NAND. Xem phần bài tập cho nhiều ví dụ hơn


[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 12/02/2009 03:32:27 (+0700) | #19 | 169128
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Đọc phần này các bạn sẽ hiểu được cấu trúc cở sở của những phép toán trong máy tính và một số cách hiển thị số.

Phần 2.62: Mạch tổ hợp

Một mạch tổ hợp là hệ thống chứa các phép toán cơ sở (AND, OR, NOT), vài đầu vào, và một tập đầu ra. Vì mỗi đầu ra tương đương với mỗi hàm logic riêng biệt, một mạch tổ hợp thường thực hiện một vài hàm logic khác nhau. Đây là điều rất quan trọng mà bạn phải nhớ – mỗi đầu ra biểu diễn một hàm boolean khác nhau.

Một CPU của máy tính được xây dựng từ các tổ hợp mạch khác nhau. Ví dụ như, bạn có thể thực hiện một mạch cộng sử dụng hàm boolean. Giả sử bạn có hai bit, A và B. Bạn có thể có được bit tổng và bit nhơ của phép cổng hai bit này sử dụng hai hàm boolean.

S = AB’ + A’B Tổng của A và B
C = AB Số nhớ từ phép cộng A và B

Hai hàm boolean này thực hiện một bộ nửa cộng. Các kỹ sư điện tử gọi nó là bộ nửa cộng bởi vì nó cộng hai bit nhưng không thể cộng bit nhớ từ phép toán trước. Một bộ cộng đầy đủ ba bit đầu vào (hai bit phép cộng và một bit nhớ mang từ phép cộng trước) và cho hai đầu ra: tổng và bit nhớ. Hai biểu thức logic cho một bộ cộng đầy đủ là:

S = A’B’Cin + A’BCin’ + AB’Cin’ + ABCin
Cout = AB + ACin + BCin

Mặc dù các biểu thức này chỉ cho ra một bit kết quả (không kể bit nhớ), nhưng thật dễ dàng để có được kết quả tổng n bit bằng cách tổ hợp đầu ra của các mạch cộng. Vì vậy, như ví dụ đã minh họa một cách rõ ràng, chúng ta có thể sử dụng các hàm logic boolean để thực hiện các phép toán đại số và boolean




Một mạch tổ hợp thông dụng khác là bộ dịch mã bảy – phân (seven-segment). Đây là mạch tổ hợp chấp nhận bốn đầu vào và xác định những đoạn nào trong bảy đoạn trên hệ LED bảy phân hiển thị bật (logic một) hay tắt (logic không). Vì một bộ mạch bảy-phân hiển thị chứa bảy giá trị đầu ra (1 cho mỗi đoạn), nên sẽ có 7 hàm logic liên kết với sự hiển thị (đoạn từ 0 tới 7). Xem các hình sau cho sự phân bố mỗi đoạn và cho sự biểu diễn các số từ không tới chín của hệ thập phân







Bốn đầu vào cho các 7 hàm boolean là bốn bit từ các số nhị phân từ 0..9. Đặt D là bit H.O. của số này và A là bit L.O. của số này. Mỗi hàm sẽ cho ra một (đoạn bật) cho một giá trị đầu vào nếu đoạn tương ứng được sáng lên. Ví dụ như S4 (đoạn 4) sẽ hiển thị trên các giá trị đầu vào 0000, 0010, 0110, và 1000 (hay ở các số 0, 2, 6, 8). Cho mỗi giá trị mà làm cho đoạn sáng lên bạn sẽ có một tiểu hạng trong hàm logic:

S4 = D’C’B’A’ + D’C’BA’ + D’CBA’ + DC’B’A’.

S0 ví dụ thứ hai, nằm trên các giá trị 1, 2, 3, 5, 6, 7,8, và 9. Vì vậy, hàm logic cho S0 là:

S0 = D’C’B’A’ + D’C’BA’ + D’C’BA + D’CB’A + D’CBA’ + D’CBA + DC’B’A’ + DC’B’A

Bạn có thể tạo năm hàm logic còn lại tương tự như trên (xem như một bài tập).

Mạch tổ hợp là cơ sở cho nhiều thành phần cơ bản của hệ thống mày tính. Bạn có thể đặt ra các mạch cộng, trừ, nhân, chia, so sáng và nhiều phép toán khác sử dụng logic tổ hợp.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 14/02/2009 14:55:10 (+0700) | #20 | 169403
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Bạn nào thích sau này làm một nhà thiết kế CPU thì nên đọc phần này kĩ hơn và nên tìm các tài liệu khác smilie

Phần 2.6.3: Tính tuần tự và clocked logic
Một vấn đề quan trọng đối với tổ hợp logic là khả năng nhớ. Trong lý thuyết, tất cả các hàm logic chỉ phụ thuộc vào các đầu vào hiện hành. Chỉ một thay đổi trong giá trị đầu vào ngay lập tức được phản ánh ở các đầu ra. Không may, máy tính cần có khả năng nhớ các kết quả của các phép tính đã qua. Đây là miền của tính tuần tự hay clocked logic.

Một bộ nhớ cơ sở là một mạch điện tử nhớ các giá trị đầu vào sau khi xóa đi giá trị đầu vào đó. Hầu hết các bộ nhớ cơ sở là đơn vị set/reset flip-flop (mạch lật flip-flop). Bạn có thể đặt ra một SR flip-flop sử dụng hai cổng NAND như sau:




Đầu vào S và R thường ở mức cao. Nếu bạn tạm thời đặt đầu vào S là 0 và sau đó mang nó trở lại thành 1 (đảo đầu vào S), điều này làm cho đầu ra Q thành 0. Tương tự, nếu bạn đảo đầu vào R từ 1 thành 0 sau đó thành 1, điều này sẽ đặt đầu ra Q thành 0. Đầu vào Q' nói chung là ngược với đầu ra Q.

Chú ý rằng nếu cả S và R là 1, thì đầu ra Q phụ thuộc vào Q. Đó là, bất kể Q là gì, thì cổng NAND trên cùng tiếp tục cho ra giá trị đầu ra như thế. Nếu Q bắt đầu là 1, thì đầu vào flip-flop ở dưới là cũng là 1 (Q và R). Điều này sẽ cho đầu ra là 0 (Q'). Vì vậy, hai đầu vào của cổng NAND trên cùng là 0 và 1. Điều này sẽ sản xuất ra giá trị một như đầu ra (phù hợp với giá trị ban đầu của Q). Nếu giá trị ban đầu của Q là 0, khi đó đầu vào của cổng NAND ở dưới là Q=0 và R=1. Vì vậy, đầu ra của cổng NAND này là 1. Đầu vào của cổng NAND trên cùng, vì vậy, sẽ là S=1 và Q'=1. Sản xuất này cho đầu ra là 0, là giá trị ban đầu của Q.

Giả sử Q là 0, S là 0 và R là 1. Điều này sẽ đặt hai đầu vào (S và R) tới flip-flop là 1 và 0, làm cho đầu ra (Q) thành 1. Khi cho S trở lại ở mức cao sẽ không làm thay đổi tất cả các đầu ra. Bạn có thể thu được kết quả tương tự nếu Q là 1, S là 0, và R là 1. Trở lại, sản xuất này sẽ cho đầu ra thành 1. Giá trị một vẫn còn lại mỗi khi S chuyển từ 0 thành 1. Vì vậy, đảo ngược đầu vào S từ 1 thành 0 và sau đó mang trở lại thành 1 sẽ cho đầu ra là 1 (set flip- flop). Với cùng ý tưởng đó khi áp dụng cho đầu vào R sẽ ép đầu ra Q thành 0 hơn là 1(reset flip-flop).

Có một điều cấm với mạch này. Nó sẽ không tính toán chính xác nếu bạn đặt đồng thời đầu vào S và R là 0. Điều này sẽ làm cho cả hai đầu ra Q và Q là 1 (mâu thuẫn). Bất cứ đầu vào nào là 0 sẽ xác định trạng thái cuối cùng của flip-flop. Một flip-flop tính toán trong trường hợp này được gọi là không ổn định.

Chỉ có một vấn đề với S/R flip-flop là bạn phải sử dụng các đầu vào riêng biệt để nhớ các giá trị 0 và 1. Một ô nhớ cở sở sẽ thêm nhiều giá trị cho chúng ta nếu chúng ta có thể xác định được giá trị dữ liệu để nhớ trên một đầu vào và thêm một đồng hồ để chốt các giá trị đầu vào. Loại flip-flop này, là D flip-flop (cho dữ liệu) sử dụng như mạch dưới đây.




Giả sử rằng bạn định đầu ra Q và Q' là 0/1 hoặc 1/0, gửi một xung đồng hồ đi từ 0 tới 1 trở lại 0 sẽ sao chép đầu vào D tới đầu ra Q. Nó cũng sẽ sao chép D' thành Q'. Phần bài tập ở cuối chương này sẽ cho bạn miêu tả các phép toán một cách cụ thể, vì vậy hãy học biểu đồ một cách cẩn thận.

Mặc dù việc nhớ một bit là rất quan trọng, nhưng trong hầu hết các hệ thống máy tính bạn sẽ muốn nhớ một nhóm bit. Bạn có thể nhớ một chuỗi bit bằng cách tổ hợp song song các D flip-flop với nhau. Liên kết các flip-flop thành nơi chứa giá trị n-bit là dạng của một thanh ghi. Biểu đồ dưới đây biểu thị cách xây dựng một thanh ghi 8-bit từ một tập D flip-flop.




Chú ý rằng 8 D flip-flop sử dụng dòng đồng hồ thông dụng. Biểu đồ này không hiển thị đầu ra Q' trên flip-flop vì chúng hiếm khi được yêu cầu trong thanh ghi.

Các D flip-flop rất hữu dụng cho việc xây dựng nhiều mạch tuần tự như trên và thanh ghi đơn giản ở trên. Ví dụ như, bạn có thể xây dựng một thanh ghi dịch bit một ví trí về bên trái trên mỗi xung đồng hồ. Thanh ghi dịch bốn bit sẽ nói ở phần sau.

Bạn có thể xây dựng một bộ đếm, để đếm số lần đồng hồ đảo trạng thái từ 1 thành 0 và sau đó trở lại 1 sử dụng flip-flop (Xem ở phần sau).

Thật ngạc nhiên, bạn có thể xây dựng một CPU hoàn toàn với mạch tổ hợp và chỉ với một vài mạch tuần tự như trên.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 16/02/2009 05:17:50 (+0700) | #21 | 169561
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Phù! Sắp hết chương hai rùi haha smilie

Phần 2.7: Okay, máy tính phải làm gì với một chương trình ?

Khi bạn đã có thanh ghi, bộ đếm, và thanh ghi dịch bit, bạn có thể xây dựng máy trạng thái. Một sự thực hiện của thuật toán trong phần cứng sử dụng máy trạng thái tốt vượt qua ngoài phạm vi của tài liệu này. Tuy nhiên, một điểm quan trọng cần phải thực hiện đối với các mạch-bất kỳ thuật toán nào bạn có thể thực hiện trong phần mềm thì bạn cũng có thể thực hiện trong phần cứng. Điều này cho thấy rằng logic boolean là cơ sở tính toán trong tất cả các máy tính hiện đại. Bất kỳ chương trình nào bạn có thể viết, bạn có thể xác định như một chuỗi các phương trình boolean.

Đương nhiên, nó sẽ dễ dàng hơn để xác định giải pháp cho một vần đề lập trình bằng cách sử dụng các ngôn ngữ như Pascal, C, hay thậm chí là assembly hơn là sử dụng các phương trình boolean. Vì vậy, sẽ không chắc rằng bạn sẽ thực hiện toàn bộ một chương trình sử dụng một tập các máy trạng thái và các mạch logic khác. Tuy vậy, cũng có vài trường hợp sự thực hiện trên phần cứng là tốt hơn. Một giải pháp phần cứng có thể là một, hai, ba, hay nhiều tập lệnh nhanh hơn một phần mềm tương đương. Vì vậy, sẽ có một vài phép toán có thể được yêu cầu trên phần cứng.

Một thực tế thú vị là điều ngược lại ở trên cũng đúng. Không chỉ bạn có thể thực hiện tất cả các hàm phần mềm trên phần cứng, mà nó cũng luôn phù hợp cho việc thực hiện tất cả các hàm của phần cứng trong phần mềm. Đây là điều phát hiện quan trọng bởi vì nhiều phép toán bạn thực hiện một cách bình thường trong phần cứng hơn là thực hiền sử dụng phần mềm trên một vi mạch. Quả thật, đây là một sử dụng cơ sở của hợp ngữ trong các hệ thống máy tính hiện đại – rẻ hơn để thay thế cho một mạch điện phức tạp.




Người ta có thể thay thế 10 hay 100 đô la của các thành phần mạch điện chỉ vởi 25 $ con chip vi mạch điện tử. Toàn bộ hệ thống nhúng sẽ giải quyết vấn đề này. Các hệ thống nhúng là hệ thống máy tính được đặt vào sản phẩm khác. Ví dụ như, hầu hết các lò vi sóng, TV, video games, CD players, và các thiết bị tiêu thụ khác chứa một hay nhiều hệ thống máy tính hoàn chỉnh có mục đích duy nhất là thay thế những bộ phận thiết kế phần cứng phức tạp. Các kỹ sư sử dụng máy tính cho mục đích này bởi vì họ sẽ ít tốn kém hơn và dễ dàng hơn để thiết kế hơn là với các mạch điện tử truyền thống.

Bạn có thể thiết kế dễ dàng thiết kế phần mềm đọc bộ ngắt mạch (các biến đầu vào) và bật máy, đèn LED, khóa hay mở khóa, vân vân...(các hàm đầu ra). Để viết một phần mềm như vậy, bạn sẽ cần hiểu biết về các hàm boolean và biết cách thực hiện các hàm trong phần mềm

Đương nhiên, có một lý do khác cho việc học các hàm boolean, dù cho bạn không có ý định viết phần mềm cho hệ thống nhúng hoặc viết phần mềm cho các thực hiện thao tác trên các thiết bị thực. Nhiều ngôn ngữ lập trình bậc cao xử lý các hàm boolean (ví dụ, các biểu thức điểu khiển if hay vòng lặp). Bằng cách áp dụng sự chuyển đổi như luật DeMorgan’s hay bản đồ tối ưu thường cải thiện quá trình thực hiện mã trên các ngôn ngữ lập trình bậc cao. Vì vậy, học các hàm boolean sẽ nâng cao trình độ của bạn dù cho bạn không có ý định trở thành nhà thiết kế mạch điện tử. Nó có thể giúp bạn viết các đoạn mã tốt hơn trong những ngôn ngữ lập trình truyền thống.

Ví dụ như, bạn có câu lệnh sau trong Pascal:

if ((x=y) and (a <> b)) or ((x=y) and (c <= d)) then SomeStmt;

Bạn có thể đơn giản nó bằng cách sử dụng luật phần phối như sau:
if ((x=y) and ((a <> b) or (c <= d)) then SomeStmt;

Tương tự, chúng ta có thể sử dụng luật DeMorgan’s để tối ưu

while (not((a=b) and (c=d)) do Something;
thành
while (a <> b) or (c <> d) do Something;

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dịch từ Art of Assembly) 19/02/2009 02:15:40 (+0700) | #22 | 169943
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Phần 2.8: Đặc tính chung của hàm boolean

Đối với một ứng dụng cụ thể, bạn có thể tạo một hàm logic mà cho một số kết quả cụ thể. Giả sử, bạn muốn viết một chương trình để mô phỏng bất kỳ hàm boolean phù hợp nào ? Ví dụ như, trên đĩa của bạn, có một chương trình cho bạn nhập một hàm boolean tùy ý từ một tới bốn biến khác nhau. Chương trình sẽ đọc đầu vào và cho kết quả của hàm. Vì số lượng các hàm bốn biến là rất lớn (65,536), không có một giải pháp thực tiễn cụ thể nào có ích cho từng hàm trong chương trình. Đặc điểm chung gì là cần thiết cho các hàm logic, một trong những đặc điểm này sẽ tính toán ra kết quả một hàm boolean bất kỳ. Phần này miểu tả cách viết một hàm như vậy.

Một đặc điểm chung của hàm boolean cho bốn biến yêu cầu 5 biến tham số – bốn tham biến đầu vào và một tham biến thứ năm xác định hàm để tính. Chúng ta sẽ bỏ số thứ tự hàm boolean vào tham biến thứ năm này.

Ban đầu khi lướt qua bạn có thể tự hỏi cách chúng ta có thể tính toán một hàm bằng cách sử dụng số thứ tự của hàm. Hãy ghi nhớ rằng các bit làm nên số thứ tự hàm được lấy trực tiếp từ bảng chân trị của hàm. Vì vậy, nếu chúng ta lấy ra các bit từ số thứ tự hàm, thì chúng ta có thể đặt ra bảng chân trị cho hàm. Thực vậy, nếu chúng ta chỉ lựa chọn bit thứ i của số thứ tự hàm, thì ở đây i=D*8 + C*4 + B*2 +A bạn sẽ có được kết quả của hàm cho các giá trị riêng biệt . Các ví dụ sau đây, trong C và Pascal sẽ cho biết cách viết hàm này.

Code:
#include <stdlib.h>
#include <stdio.h>
int
generic(int func, int a, int b, int c, int d)
{
        /* Trả lại bit được định bởi a, b, c, d */
        
        return (func >> (a + b*2 + c*4 + d*8)) & 1; /* ">>", "&" là toán tử dịch phải và AND trong C */
}

{
        int func, a, b, c, d;
        /* Lặp lại cho tới khi nhập vào không          */
        
        do
        {          
                
                printf(“Enter function value (hex): “);
                scanf(“%x”, &func);
                
                if (func != 0)
                {
                        printf(“Enter values for d, c, b, & a: “);
                        scanf(“%d%d%d%d”,
                                &d, &c, &b, &a);
                        printf(“The result is %d\n”, generic(func,a,b,c,d));
                        printf(“Func = %x, A=%d, B=%d, C=%d, D=%d\n”,
                                func, a, b, c, d);
                }
                
                
        } while (func !=0);


Chương trình Pascal sau được viết theo Pascal tiêu chuẩn. Pascal tiêu chuẩn không cung cấp bất kỳ một phép toán thao tác nào trên bit, vì vậy chương trình này sẽ dài dòng bởi vì nó phải mô phỏng các bit sử dụng mảng các số nguyên. Hầu hết các trình dịch Pascal tiên tiến (đặc biệt như là Turbo Pascal) cung cấp các phép toán xây dựng bit hay các thư viện để tính toán trên bit. Chương trình này dễ viết hơn nếu sử dụng các chức năng không chuẩn.

Code:
program GenericFunc(input,output);

type
    gftype = array [0..15] of integer;
var
   a, b, c, d:integer;
   fresult    :integer;
   func       : gftype;

procedure ShiftLeft(shiftin:integer);  { Dịch trái một ví trí và dịch bit shiftin vào bit 0 }
var i         :integer;
begin
     for i := 15 downto 1 do func[i] := func[i-1];
     func[0] := shiftin;
end;

procedure ShiftNibble(d,c,b,a:integer); { Dịch trái bốn vị trí }
begin
     ShiftLeft(d);
     ShiftLeft(c);
     ShiftLeft(b);
     ShiftLeft(a);
end;

procedure ShiftRight;                      { Dịch phải một vị trí và dịch không vào bit 15 }
var i:integer;
begin
     for i := 0 to 14 do func[i] := func[i+1];
     func[15] := 0;
end;

procedure toupper(var ch:char);     { Chuyển thành ký tự hoa }
begin
     if (ch in [‘a’..’z’]) then ch := chr(ord(ch) - 32);
end;

function ReadFunc:integer;           { Đọc số thứ tự hàm }
var ch:char;
    i, val:integer;
begin
     write(‘Enter function number (hexadecimal): ‘);
     for i := 0 to 15 do func[i] := 0;
     repeat
           read(ch);
           if not eoln then begin                   { Khi chưa kết thúc dòng }
                      toupper(ch);
                      case ch of
                           ‘0’: ShiftNibble(0,0,0,0);
                           ‘1’: ShiftNibble(0,0,0,1);
                           ‘2’: ShiftNibble(0,0,1,0);
                           ‘3’: ShiftNibble(0,0,1,1);
                           ‘4’: ShiftNibble(0,1,0,0);
                           ‘5’: ShiftNibble(0,1,0,1);
                           ‘6’: ShiftNibble(0,1,1,0);
                           ‘7’: ShiftNibble(0,1,1,1);
                           ‘8’: ShiftNibble(1,0,0,0);
                           ‘9’: ShiftNibble(1,0,0,1);
                           ‘A’: ShiftNibble(1,0,1,0);
                           ‘B’: ShiftNibble(1,0,1,1);
                           ‘C’: ShiftNibble(1,1,0,0);
                           ‘D’: ShiftNibble(1,1,0,1);
                           ‘E’: ShiftNibble(1,1,1,0);
                           ‘F’: ShiftNibble(1,1,1,1);
                           else write(chr(7),chr(8));
                      end;
           end;
     until eoln;
     val := 0;
     for i := 0 to 15 do val := val + func[i];
     ReadFunc := val;
end;

function Generic(var func:gftype; a,b,c,d:integer):integer;
begin
          Generic := func[a + b*2 + c*4 + d*8];
end;
begin { Chương trình chính }
      repeat
            fresult := ReadFunc;
            if (fresult <> 0) then begin
               write(‘Enter values for D, C, B, & A (0/1):’);
               readln(d, c, b, a);
               writeln(‘The result is ‘,Generic(func,a,b,c,d));
            end;
      until fresult = 0;
end.


Đoạn mã sau đây miêu tả các phép toán thao tác trên bit. Phiên bản này của đoạn mã trên sử dụng các đặc điểm đặc biệt trong trình biên dịch Turbo Pascal cho phép người lập trình sử dụng dịch trái hoặc dịch phải để lấy một bit bằng logic AND trên giá trị nguyên:

Code:
program GenericFunc(input,output);
const
     hex = [‘a’..’f’, ‘A’..’F’];
     decimal = [‘0’..’9’];
var
        a, b, c, d:integer;
   fresult:integer;
   func: integer;

function ReadFunc:integer;
var ch:char;
    i, val:integer;
begin
     write(‘Enter function number (hexadecimal): ‘);
     repeat
           read(ch);
           func := 0;
           if not eoln then begin
              if (ch in Hex) then 
                func := (func shl 4) + (ord(ch) and 15) + 9
              else if (ch in Decimal) then 
                func := (func shl 4) + (ord(ch) and 15)
              else write(chr(7));
           end;
     until eoln;
     ReadFunc := func;
end;

function Generic(func,a,b,c,d:integer):integer;
begin
          Generic := (func shr (a + b*2 + c*4 + d*8)) and 1;
end;
begin (* main *)
      repeat
            fresult := ReadFunc;
            if (fresult <> 0) then begin
               write(‘Enter values for D, C, B, & A (0/1):’);
               readln(d, c, b, a);
               writeln(‘The result is ‘,Generic(func,a,b,c,d));
            end;
      until fresult = 0;
end.


Giải thích một tý về đoạn mã tiêu chuẩn Pascal:

-Mảng như là số thứ tự các bit từ 0..15
-Hàm shiftnibble dùng để dịch 4 bit trong mảng
Giả sử bạn nhập vào các giá trị 3, 4, 5, 6 cho hàm thì khi này đoạn mã "if not eoln then begin ...end" sẽ thực hiện, đầu tiên nó sẽ dịch các giá trị (0, 0, 1, 1) vào func[0]..func[3], sau đó nó dịch các giá trị (0, 1, 0, 0) vào func[0]..func[3] và dịch các giá trị (0, 0, 1, 1) vào func[4]..func[7]...Tương tự cho tới khi kết thúc chúng ta thu được mảng chứa các bit nhị phân liên tiếp của số thứ tự hàm.
Cuối cùng, chương trình này không sử dụng dịch phải do có thể truy xuất từng giá trị trong mảng

smilie smilie

The end of chapter two
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 19/02/2009 23:01:32 (+0700) | #23 | 170050
[Avatar]
phamthaiha
Member

[Minus]    0    [Plus]
Joined: 08/11/2004 18:09:01
Messages: 57
Offline
[Profile] [PM]
Mẹ ơi ,lại nhớ đến những ngày học đại học ,bù đầu với những thuật toán ,sơ đồ và bảng mạnh ,đi dây cứ gọi là smilie
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 20/02/2009 03:38:49 (+0700) | #24 | 170122
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]

phamthaiha wrote:
Mẹ ơi ,lại nhớ đến những ngày học đại học ,bù đầu với những thuật toán ,sơ đồ và bảng mạnh ,đi dây cứ gọi là smilie 


Trời ! nghe bác nói mà trông khiếp quá nhưng em hai năm nữa mới thi đại học không biết thế nào nhỉ hihi smilie

Cái này tuy đơn giản nhưng không thể không up lên, for newbie mà lị smilie

Chương 3: Tổ chức hệ thống máy tính

Phần 3.1: Các thành phần hệ thống cơ sở

Các bộ phận hoạt động cơ bản của hệ thống máy tính được gọi là cấu trúc của nó. John Von
Neumann, người tiên phong trong thiết kế máy tính, đã đưa ra một cấu trúc cho hầu hết các máy tính hiện nay. Ví dụ, họ 8086 sử dụng cấu trúc Von Neumann (VNA). Một hệ thống Von Neumann tiêu biểu có ba thành phần chính: khối sử lý trung tâm (CPU), bộ nhớ, và input/output (hay I/O). Cách mà một nhà thiết kế hệ thống kết hợp các thành phần đó sẽ ảnh hưởng trực tiếp tới hiệu suất của hệ thống.




Trong một máy VNA, như họ 8086, CPU là nơi thực hiện tất cả các hành động. Tất cả các phép tính xảy ra trong CPU. Dữ liệu và các lệnh CPU nằm trong bộ nhớ cho tới khi chúng được yêu cầu bởi CPU. Nối với CPU, hầu hết các thiết bị I/O như các bộ nhớ bởi vì CPU có thể lưu trữ dữ liệu tới các thiết bị đầu ra và đọc dữ liệu từ các thiết bị đầu vào. Sự khác biệt lớn nhất giữa bộ nhớ và các địa chỉ I/o là các I/O thường kết hợp với thiết bị ngoài trong thế giới.

Phần 3.1.1: Hệ thống Bus

Hệ thống bus kết nối những thành phần khác nhau của một máy VNA. Họ 80-86 có ba loại bus chính: bus địa chỉ, bus dữ liệu, và bus điều khiển. Một bus là tập hợp các dây điện mà trong đó nó kết nối tới các thành phần của hệ thống. Các bus đó có chức năng khác nhau để xử lý các công việc khác nhau. Tuy nhiên, mỗi bus mang các thông tin có thể so sánh được trên mọi bộ xử lý; ví dụ bus dữ liệu có thể có sự thực hiện khác nhau trên 80386 và 8088, nhưng cả hai đều mang dữ liệu giữa vi mạch, I/O, và bộ nhớ.

Một hệ thống các thành phần 8086 sử dụng mức logic TTL tiêu chuẩn (standard TTL logic levels.). Điều này nghĩa là mỗi mạch điện trên một bus sử dụng một mức suất điện động tiêu chuẩn để biểu diễn 0 và 1. Chúng ta sẽ luôn luôn sử dụng 0 và 1 hơn là các mức điện bởi vì sẽ có các mức khác nhau trong các vi mạch khác nhau (đặc biệt là máy tính xách tay).



[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 22/02/2009 10:49:53 (+0700) | #25 | 170446
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Tiếp tục nè

Phần 3.1.1.1: Bus dữ liệu

Vi mạch 8086 sử dụng bus dữ liệu để sắp xếp dữ liệu giữa các thành phần khác nhau trong hệ thống máy tính. Cỡ của bus này thay đổi khắp trong họ 8086. Thực vậy, bus này định nghĩa cho “cỡ” của một vi mạch.

Trên một hệ thống 8086 điển hình, bus dữ liệu chứa 8, 32, hoặc 64 dòng. Các chip vi mạch 8088 và 80188 có 8 bit dữ liệu bus (8 dòng dữ liệu). Các vi mạch 80386DX, 80486, và Pentium Over-drive có 32 bit bus dữ liệu. Vi mạch Pentium và Pentium Pro có 64 bit bus dữ liệu. Các phiên bản trong tương lai (có thể là 80686/80786) có thể có bus dữ liệu lớn hơn.

“Cỡ” của một vi mạch
Hiện đã có một vài bất đồng giữa các kỹ sư phần cứng và phần mềm liên quan tới “cỡ” của vi mạch như 8088. Từ một nhà thiết kế phần cứng, thì 8088 hoàn toàn chỉ là một vi mạch 8 bit - nó chỉ có 8 dòng dữ liệu và có bus tương thích với bộ nhớ và thiết bị I/O được thiết kế cho các bộ xử lý 8 bit. Kỹ sư phần mềm, mặt khác, đã có ý kiến 8088 là bộ xử lý 16 bit. Từ viễn cảnh đó thì họ cũng không thể phân biệt giữa 8088 (với 8 bit bus dữ liệu) và 8086 (có 16 bit bus dữ liệu). Thực tế, chỉ có sự khác nhau là tốc độ tính toán của các vi mạch; 8086 với 16 bit bus nhanh hơn. Cuối cùng người thiết kế phần cứng chiến thắng. Thực tế là các kỹ sư phần mềm không thể phần biệt được 8088 và 8085 trong chương trình của họ, chúng ta gọi 8088 là bộ xử lý 8 bit và 8086 là bộ xử lý 16 bit. Tương tự, 80380SX (có 16 bit bus dữ liệu) là vi mạch 16 bit trong khi 80386DX (có đầy đủ 32 bit bus dữ liệu) là vi mạch 32 bit.



Việc có 8 bit dữ liệu không hạn chế bộ xử lý tới các loại dữ liệu 8 bit. Nó đơn giản chỉ là vi mạch có thể truy cập một byte của dữ liệu trên mỗi chu kỳ nhớ (xem ở phần “Phân hệ bộ nhớ” cho việc miêu tả một chu kỳ nhớ). Vì vậy, 8 bit bus trên 8088 chỉ có thể truyền tải thông tin (chu kỳ nhớ) bằng một nửa thời gian của các bus 16 bit trên 8086. Do đó, vi mạch với 16 bit bus đương nhiên nhanh hơn 8 bit bus. Tương tự, vi mạch với 32 bit bus nhanh hơn với vi mạch 16 bit bus. Cỡ của bus dữ liệu ảnh hưởng trực tiếp tới quá trình thực hiện của hệ thống hơn là cỡ các bus khác.

Bạn sẽ thường xuyên nghe một vi mạch được gọi là vi mạch 8, 32, 64 bit. Trong khi có một sự bàn cãi nhỏ về cỡ của một vi xử lý, hầu hết mọi người ngay bây giờ đồng ý rằng số lượng dòng dữ liệu trên một vi xử lý xác định kích cỡ của nó. Vì họ bus 8086 là 8, 16, 32, hay 64 bit, hầu hết các dữ liệu được truy cập cũng là 8, 16, 32, hay 64 bit. Mặc dù có thể xử lý dữ liệu 12 bit với 8088, nhưng hầu hết các lập trình viên xử lý với 16 bit vì các vi xử lý sẽ nạp và thao tác với 16 bit. Đây là vì các vi xử lý luôn luôn lấy 8 bit. Để lấy được 12 bit thì cần yêu cầu hai phép toán bộ nhớ 8 bit. Vì các vi xử lý sẽ xử lý 16 bit hơn là 12 bit, nên hầu hết các lập trình viên sử dụng 16 bit. Nói chung, các dữ liệu được xử lý với 8, 16, 32, hay 64 bit là hiệu quả nhất.




Phần 3.1.1.2: Bus địa chỉ

Bus dữ liệu trên họ vi mạch 8086 chuyển dữ các thông tin giữa một vị trí nhớ đặc biệt hay I/O và CPU. Chỉ có một câu hỏi là, “Cái gì xác định địa chỉ bộ nhớ hoặc thiết bị I/O ?”. Bus địa chỉ là câu trả lời cho câu hỏi này. Để phân biệt giữa địa chỉ nhớ và thiết bị I/O, các nhà thiết kế hệ thống gán mỗi địa chỉ bộ nhớ cho mỗi phần tử nhớ và thiết bị I/O. Khi phần mềm muốn truy cập một vài các địa chỉ nhớ khác nhau hay thiết bị I/O, nó đặt các địa chỉ nhớ tương đương lên bus địa chỉ. Hệ mạch điện được kết nối với bộ nhớ hay thiết bị I/O để nhận diện địa chỉ này và ra chỉ thị tới bộ nhớ hoặc thiết bị I/O để đọc dữ liệu từ nơi đặt dữ liệu trên bus dữ liệu.
Trong mọi trường hợp, mọi địa chỉ nhớ khác đều bị bỏ qua. Chỉ những thiết bị có địa chỉ phù hợp với giá trị trên bus địa chỉ mới được đáp ứng.

Với một dòng địa chỉ, một vi mạch có thể tạo ra chính xác hai giá trị địa chỉ duy nhất: 0 và 1. Với n dòng địa chỉ, vi mạch có thể cho 2^n giá trị địa chỉ duy nhất (vì chỉ có duy nhất 2^n giá trị trong n bit nhị phân). Vì vậy, số lượng bit trên bus địa chỉ sẽ xác định số lượng tối đa của bộ nhớ khả định và địa chỉ I/O. Với 8088 và 8086, ví dụ, có 20 bit bus địa chỉ. Do đó,chúng có thể truy cập tới 1,048,576 (hay 2^20) địa chỉ bộ nhớ. Bus địa chỉ lớn hơn có thể truy cập nhiều địa chỉ hơn. 8088 và 8086. The 8088 and 8086, for example, suffer from an anemic address space2 – their address bus is too small (cái này chả hiểu nó nói cái gì). Các vi xử lý đời sau sẽ có bus địa chỉ lớn hơn.




Các bộ xử lý 8086 tương lai có lẽ sẽ hổ trợ 48 bit bus địa chỉ. Vào thời gian tới khi hầu hết các lập trình viên sẽ cho rằng bốn gigabytes lưu trữ là quá nhỏ, giống như họ thấy một megabyte là không đủ ngày hôm nay. (Có một thời gian một megabyte được cho rằng là quá đủ so với những gì chúng ta cần). May thay, những kiến trúc 80386, 80480, và những con chip sau này cho phép mở rộng tới 48 bit bus địa chỉ qua sự phân các đoạn.

Phần 3.1.1.3: Bus điều khiển

Bus điều khiển là tập hợp của các mạch tín hiệu điều khiển của vi xử lý giao tiếp với những phần còn lại của hệ thống. Xét một bus dữ liệu hiện tại. CPU sẽ gửi dữ liệu tới bộ nhớ và nhận dữ liệu từ bộ nhớ trên bus dữ liệu. Điều này phát sinh một câu hỏi, “Nó đang gửi hay đang nhận ?” Có hai dòng trên bus điều khiển, đọc và viết, để định hướng dòng dữ liệu. Những tín hiệu khác bao gồm đồng hồ hệ thống, dòng ngắt, dòng trạng thái, và vân vân. Sự tạo thành của bus điều khiển tạo ra sự khác nhau giứa các họ vi mạch 8086. Tuy nhiên, một vài dòng điều khiển là thông dụng với tất cả các vi mạch và có giá trị.

Các dòng điều khiển đọc và viết là sự điều khiển dữ liệu trên bus dữ liệu. Khi cả hai đều chứa logic 1, CPU và bộ nhớ-I/O không giao tiếp với nhau. Nếu dòng đọc ở mức thấp (logic 0), CPU sẽ đọc dữ liệu từ bộ nhớ (đó là, hệ thống sẽ chuyển dữ liệu từ bộ nhớ đến CPU). Nếu dòng viết ở mức thấp, hệ thống sẽ chuyển dữ liệu ngược trở lại từ CPU đến bộ nhớ.

Các dòng byte là một bộ phận quan trọng của dòng điều khiển. Các dòng điểu khiển đó cho phép bộ xử lý 16, 32, và 64 bit để xử lý các mẩu dữ liệu nhỏ hơn. Thông tin chi tiết sẽ được nói trong phần tới.

Họ 8086, không giống như các vi xử lý khác, cung cấp hai địa chỉ không gian nhớ khác biệt: một cho bộ nhớ và một cho I/O. Trong khi bus địa chỉ nhớ trên các vi mạch 8086 khác nhau thì khác nhau về cỡ, thì các bus địa chỉ I/O trên tất cả CPU 8086 đều là 16 bit. Điều này cho phép bộ xử lý truy cập tới 65,536 các địa chỉ I/O khác nhau. Khi nó được gọi ra, hầu hết các thiết bị (như bàn phím, máy in, ổ đĩa...) yêu cầu nhiều hơn một địa chỉ I/O khác nhau. Tuy nhiên, 65,536 địa chỉ I/O là quá đủ cho hầu hết các ứng dụng. Các máy tính IBM được thiết kế ban đầu chỉ cho phép sử dụng 1,024 trong số các địa chỉ đó.

Mặc dù họ 8086 hỗ trợ hai không gian địa chỉ, nhưng nó không có hai bus địa chỉ (cho I/O và bộ nhớ). Thay vào đó, hệ thống chia sẽ bus địa chỉ cho cả hai địa chỉ I/O và địa chỉ bộ nhớ. Các dòng bus điều khiển được bổ sung vào xem xét địa chỉ được dự định là bộ nhớ hay I/O. Khi các tín hiệu hoạt động, các thiết bị I/O sẽ sử dụng các địa chỉ trên 16 bit L.O. của bus địa chỉ. Khi không hoạt động, các thiết bị I/O sẽ bỏ qua các tín hiệu trên bus địa chỉ (hệ thống nhớ sẽ trực tiếp xử lý tại điểm đó).

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 24/02/2009 14:12:32 (+0700) | #26 | 170714
vnexpl0it
Member

[Minus]    0    [Plus]
Joined: 16/02/2009 17:51:52
Messages: 5
Offline
[Profile] [PM] [WWW] [Yahoo!]
Thanks, Good Job smilie

Nhưng mừ sao không viết kiểu ebook rồi up lên. Kiểu này khó đọc khó theo dõi ghê.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 24/02/2009 18:09:27 (+0700) | #27 | 170732
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]

vnexpl0it wrote:
Thanks, Good Job smilie

Nhưng mừ sao không viết kiểu ebook rồi up lên. Kiểu này khó đọc khó theo dõi ghê. 


Sorry vì sự bất tiện này nhưng bác tha cho em, em chả có thời gian đâu. Nhưng cứ ba chương em sẽ đóng thành ebook riêng cho mọi người (đương nhiên sẽ có phần bài tập trong đó). Thân smilie

Phần 3.1.2: Hệ thống bộ nhớ

Một bộ vi xử lý 80886 điển hình có tối đa 2^n các địa chỉ bộ nhớ khác nhau, ở đây n là số bit trên bus địa chỉ. Như bạn đã thấy, vi xử lý 8086 có 20, 24, và 32 bit bus địa chỉ (tương lai sẽ là 48 bit).

Đương nhiên, câu hỏi đầu tiên bạn nên hỏi là, “Có chính xác bao nhiêu địa chỉ bộ nhớ?”. 8086 hỗ trợ các bộ nhớ với địa chỉ là các byte. Vì vậy, hệ bộ nhớ cơ sở là một byte. Với 20, 24, 32 dòng địa chỉ, vi mạch 8086 có thể định 1 megabyte, 16 megabyte, và 4 gigabyte địa chỉ của bộ nhớ.

Coi bộ nhớ như là một mảng của các byte. Địa chỉ của byte đầu tiên là 0 và địa chỉ byte cuối cùng là 2^n-1. Cho vi xử lý 8086 với 20 bit bus địa chỉ, một mảng bằng Pascal sau đây là sự miêu tả tốt cho bộ nhớ:

Memory: array [0..1048575] of byte;

Để thực hiện tương đương với câu lệnh Pascal “Memory [125]:=0;”, CPU sẽ đặt giá trị 0 trên bus dữ liệu, đặt địa chỉ 125 trên bus địa chỉ, và xác định dòng viết (vì CPU sẽ viết dữ liệu vào bộ nhớ):




Để thực hiện tương đương với câu “CPU:=Memory [125];” CPU sẽ đặt địa chỉ 125 trên bus địa chỉ, xác định dòng đọc (vì CPU sẽ đọc dữ liệu từ bộ nhớ), và sau đó đọc dữ liệu được truyền đi từ bus dữ liệu:




Những điều được nói ở trên chỉ được áp dụng khi truy cập một byte trong bộ nhớ. Vì vậy điều gì sẽ xảy ra khi bộ xử lý truy cập một word hay một double word ? Vì bộ nhớ bao gồm mảng các byte, vậy cách mà chúng ta có thể xử lý với một giá trị lớn hơn tám bit như thế nào?.

Các hệ thống máy tính khác nhau có các cách giải quyết vấn đề này khác nhau. Họ 8086 xử lý vấn đề này bằng cách chứ các L.O. byte của một word và một địa chỉ được chỉ định và H.O. byte và địa chỉ tiếp theo đó. Vì vậy, một word sẽ dùng hai địa chỉ nhớ liền nhau (như bạn mong đợi, vì một word bao gồm hai byte). Tương tự, một double word sử dụng bốn địa chỉ nhớ liền nhau. Địa chỉ cho một double word là địa chỉ L.O. byte của nó. Ba byte còn lại sau L.O. byte này, với H.O. byte xuất hiện ở địa chỉ double word cộng với ba:




Byte, word, và double word có thể bắt đầu tại một địa chỉ phù hợp nào trong bộ nhớ. Chúng ta sẽ sớm thấy, bắt đầu từ một đối tượng lớn hơn từ một địa chỉ tùy ý không phải là một ý tưởng tốt.

Chú ý rằng hoàn toàn phù hợp cho các giá trị byte, word, và double word phủ lên nhau trong bộ nhớ. Ví dụ như, ở hình trên bạn có thể có một word bắt đầu tại địa chỉ 193, một byte tại địa chỉ 194, và một giá trị double word bắt đầu tại địa chỉ 192. Tất cả các giá trị đó phủ lên nhau.

Các vi xử lý 8088 và 80188 có 8 bit bus dữ liệu. Điều này nghĩa là CPU có thể chuyển 8 bit dữ liệu tại một thời điểm. Vì mỗi địa chỉ nhớ tương đương với một byte 8 bit, nên điều này trở thành sự sặp xếp thuận tiện nhất (nó phù hợp luôn với phần cứng):




Thuật ngữ “mảng bộ nhớ có địa chỉ byte” nghĩa là CPU có thể gọi bộ nhớ trong từng mẫu như là một một byte. Nó cũng có nghĩa là đơn vị nhỏ nhất của bộ nhớ mà bạn có thể truy cập
bất cứ lúc nào với bộ xử lý. Đó là, nếu bộ xử lý muốn truy cập tới một giá trị 4 bit, nó phải đọc 8 bit và sau đó bỏ qua bốn bit thêm. Cũng nhận thấy rằng khả năng định vị của byte không có nghĩa là CPU có thể truy cập tới 8 bit trên một giới hạn bit bất kỳ nào. Khi bạn chỉ định địa chỉ 125 trong bộ nhớ, bạn có được hoàn toàn 8 bit tại địa chỉ đó, không thêm, không bớt. Các địa chỉ là các số nguyên; bạn không thể, ví dụ như, chỉ định địa chỉ 125.5 để lấy giá trị ít hơn 8 bit.

8088 và 80188 có thể thao tác trên các giá trị word và double word, chỉ với 8 bit bus dữ liệu. Tuy nhiên, điều này yêu cầu phải thực hiện nhiều thao tác trên bộ nhớ bởi vì các bộ xử lý này chỉ có thể chuyển 8 bit của dữ liệu tại một thời điểm. Để đọc một word cần hai thao tác bộ nhớ; để đọc một double word cần 4 thao tác bộ nhớ.

Các vi mạch 8086, 80186, 80286, và 80386sx có 16 bit bus dữ liệu. Điều này cho phép các bộ xử lý này truy cập gấp hai lần bộ nhớ với cùng lượng thời gian như là 8 bit của các bộ xử lý đời trước họ vi mạch này. Các vi mạch này tổ chức bộ nhớ trong hai ngân hàng dữ liệu: một ngân hàng ”chẵn” (even) và một ngân hàng “lẻ” (odd):




Hình sau minh họa sự kết nối tới CPU (D0-D7 là ký hiệu L.O. byte của bus dữ liệu, D8-D15 là ký hiệu của H.O. byte của bus dữ liệu):




Với 16 bit, thành viên của họ 8086 có thể đọc một word từ một địa chỉ bất kỳ. Như đã đề cập ở trên, bộ xử lý lấy các byte L.O. của giá trị từ địa chỉ được chỉ định và byte H.O. từ địa chỉ tiếp đó. Điều này tạo ra một vần đề khó phát hiện nếu bạn xem xét cẩn thận biểu đồ trên. Điều gì sẽ xảy ra nếu bạn truy cập một word trên một địa chỉ lẻ ? Giả sử bạn muốn đọc một word từ một địa chỉ 125. Okay, byte L.O. của word lấy từ địa chỉ 125 và byte H.O. của word được lấy từ địa chỉ 126. Có điều gì ghê gớm ở đây? Nó làm phát sinh hai vấn đề với những điều nói trên.

Đầu tiên, hãy nhìn lại hình trên. Dòng bus dữ liệu từ 8 tới 15 (byte H.O.) kết nối tới ngân hàng lẻ, và dòng bus dữ liệu 0 tới 7 (byte L.O.) kết nối tới ngân hàng chẵn. Truy cập địa chỉ bộ nhớ 125 (odd) sẽ truyền dữ liệu tới CPU trên byte H.O. của bus dữ liệu; nhưng chúng ta muốn dữ liệu này trong L.O. byte! Thật may mắn, CPU 8086 nhận biết được tình trạng này và tự động chuyển dữ liệu trên D8-D15 thành byte L.O. Nếu bạn truy cập một word từ một địa chỉ chẵn, CPU có thể mang lại hoàn toàn 16 bit trong một thao tác bộ nhớ. Tương tự, nếu bạn truy cập một byte, CPU

Vần đề thứ hai là khó nhận biết hơn. Khi truy cập các word, chúng ta truy cập vào hai byte riêng biệt, mỗi một cái đều có một địa chỉ byte riêng. Vì vậy câu hỏi đặt ra là, “Các địa chỉ gì xuất hiện trên bus địa chỉ ?” CPU 8086 luôn luôn đặt các địa chỉ chẵn vào bus. Các byte chẵn luôn luôn xuất hiện trên dòng dữ liệu D0-D7 và byte lẻ luôn luôn xuất hiện trên dòng dữ liệu D8-D15. Nếu bạn truy cập một word tại một địa chỉ chẵn, CPU có thể kích hoạt vào ngân hàng thích hợp (sử dụng một “byte kích hoạt”(byte enable) của dòng điều khiển). Nếu byte xuất hiện tại địa chỉ lẻ, CPU sẽ tự động chuyển đổi nó từ byte H.O. trên bus thành byte L.O.

Vì vậy cái gì sẽ xảy ra khi CPU truy cập một word tại một địa chỉ lẻ, như ví dụ trước đó ? CPU không thể đặt địa chỉ 125 vào trên bus địa chỉ và đọc 16 bit từ bộ nhớ. Không có một đỉa chỉ lẻ nào từ 16 bit CPU 8086. Các địa chỉ luôn luôn chẵn. Vì thể nếu bạn cố gắng đặt 125 lên bus địa chỉ, điều này sẽ đặt giá trị 124 lên bus địa chỉ. Bạn muốn đọc 16 bit tại địa chỉ này, nhưng bạn sẽ nhận được word tại địa chỉ 124 (byte L.O.) và 125 (byte H.O.) - không phải những gì mà bạn mong chờ. Truy cập một word tại một địa chỉ lẻ yêu cầu hai thao tác trên bộ nhớ. Đầu tiên CPU phải đọc các byte tại địa chỉ 125, sau đó nó cần đọc byte ở địa chỉ 126. Cuối cùng, nó cần tráo đổi vị trí của các byte nhập vào CPU đó trên một nửa sự nhầm lẫn của bus dữ liệu

May mắn, 16 bit CPU 8086 sẽ ẩn đi những thông tin từ bạn. Chương trình của bạn có thể truy cập một word tại một địa chỉ và CPU sẽ làm truy cập chính xác và tráo đổi (nếu cần thiết) dữ liệu trong bộ nhớ. Tuy nhiên, để truy cập tới một word tại một địa chỉ lẻ thì phải cần hai thao tác bộ nhớ (giống như 8088/80188). Vì vậy, truy cập một word tại địa chỉ lẻ trên vi xử lý 16 bit sẽ chậm hơn truy cập word tại địa chỉ chẵn. Cẩn thận với cách sắp xếp và sử dụng bộ nhớ, bạn có thể cải thiện tốc độ chương trình của bạn

Truy cập 32 bit luôn luôn cần dùng ít nhất hai thao tác bộ nhớ trên vi xử lý 16 bit. Nếu bạn truy cập chuỗi 32 bit tại địa chỉ lẻ, vi mạch sẽ cần tới 3 thao tác bộ nhớ để có thể truy cập dữ liệu.

Các vi xử lý 32 bit 8086 (80386, 80486, và Pentium Overdrive) sử dụng bốn ngân hàng của bộ nhớ để kết nối với 32 bit bus dữ liệu:




Các địa chỉ được đặt trên bus địa chỉ luôn luôn chia hết cho 4. Sử dụng các dòng “byte kích hoạt”, CPU có thể lựa chọn bốn byte tại địa chỉ mà phần mềm muốn truy cập. Như với vi xử lý 16 bit, CPU sẽ tự động sắp xếp lại các byte nếu như cần thiết.

Với 32 bit bộ nhớ, CPU 8086 có thể truy cập tới một vài byte chỉ với một thao tác bộ nhớ. Nếu địa chỉ chia cho 4 không dư 3, thì CPU 32 bit có thể truy cập một word tại địa chỉ đó sử dụng một thao tác bộ nhớ đơn giản. Tuy nhiên, nếu ngược lại là ba, thì nó sẽ cần dùng tới hai thao tác bộ nhớ để truy cập một word:




Đây cũng là vấn đề xảy ra với vi xử lý 16 bit, ngoài trừ một điều là nó xảy ra thường xuyên hơn.

Một CPU 32 bit có thể truy cập một double word trong một thao tác bộ nhớ nếu địa chỉ chia hết cho 4. Nếu không, CPU sẽ cần tới hai thao tác bộ nhớ. Lại một lần nữa, CPU xử lý tất cả điều này hoàn toàn tự động. Dưới dạng dữ liệu đúng CPU xử lý mọi thứ cho bạn. Tuy nhiên, hiệu suất làm việc sẽ tăng lên đáng kể nếu như sắp xếp dữ liệu thích hợp. Như một quy tắc chung bạn nên luôn luôn đặt các giá trị word vào địa chỉ chẵn và double word vào địa chỉ chia hết cho 4. Điều này sẽ tăng tốc độ cho chương trình của bạn.


[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 27/02/2009 03:27:12 (+0700) | #28 | 171151
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
smilie smilie smilie

Phần 3.1.3: Hệ thống I/O

Ngoài các dòng địa chỉ 20, 24, hay 32 bit truy cập vào bộ nhớ, họ 8086 còn cung cấp một bus địa chỉ I/O 16 bit. Điều này mang lại cho CPU 8086 hai không gian địa chỉ riêng biệt: một cho bộ nhớ và một cho các thao tác trên I/O. Dòng trên bus điều khiển phân biệt giữa bộ nhớ và địa chỉ I/O. Trừ những dòng điều khiển và bus nhỏ hơn, thì địa chỉ I/O được thi hành chính xác như địa chỉ bộ nhớ. Bộ nhớ và thiết bị I/O cùng chia sẻ bus dữ liệu và 16 dòng L.O. trên bus địa chỉ.

Có ba giới hạn cho hệ thống I/O trên máy tính cá nhân IBM (IBM PC): đầu tiên, CPU 8086 yêu cầu các chỉ thị đặc biệt để truy nhập và thiết bị I/O; thứ hai, các nhà thiết kế IBM PC sử dụng các địa chỉ I/O “tốt nhất” cho những mục đích riêng của họ, buộc những nhà phát triển thứ ba sử dụng các địa chỉ truy cập được ít hơn; thứ ba, hệ thống 8086 có thể định địa chỉ không nhiều hơn 65,526 (2^16) địa chỉ I/O. Khi bạn xem xét một card VGA điển nào đó yêu cầu hơn 128,000 địa chỉ khác nhau, thì bạn có thể thấy một vấn đề với cỡ của bus I/O. Đây là, chẳng hạn, hiển thị các thiết bị tiếp hợp trên IBM PC.

Truy cập vào thiết bị I/O là nội dung chính mà chúng ta sẽ thảo luận trong những chương sau. Còn bây giờ bạn có thể cho rằng các địa chỉ I/O và địa chỉ bộ nhớ làm việc theo cùng một cách.

smilie smilie smilie

Phần 3.2: Sự tính toán thời gian hệ thống

Mặc dù các máy tính hiện đại rất nhanh và dần trở nên nhanh hơn, nhưng chúng vẫn cần một lượng thời gian hạn chế để thực hiện ngay cả với những công việc nhỏ nhất. Trên máy Von Neumann, như 8086, đa số các phép toán được xếp theo thứ tự. Điều này nghĩa là máy tính thi hành những lệnh trong những thủ tục được quy định. Nó sẽ không làm, chẳng hạn, để thi hành câu lệnh I:=I*5+2; trước I:=j; mà trong dãy lệnh sau:

I := J;
I := I * 5 + 2;

Rõ ràng chúng ta cần một con đường để điều khiển câu lệnh nào thực hiện đầu tiên và cái nào thực hiện thứ hai.

Đương nhiên, trên tất cả các hệ thống máy tính, các phép toán không xảy ra ngay lập tức.
Dịch chuyển bản sao của J vào I mất một khoảng thời gian nhất định. Tương tự, nhân I với năm và sau đó cộng với hai và chứa kết quả vào I cũng cần thời gian. Như bạn nghĩa; câu lện Pascal thứ hai ở trên cần dùng chuỗi bit dài hơn để thi hành hơn là cái đầu tiên. Đối với những ai quan tâm tới việc viết phần mềm chạy nhanh, thì một câu hỏi tự nhiên đặt ra là, “Các mà các bộ xử lý thi hành các lệnh, và cách mà chúng ta ước lượng thời gian thực hiện của chúng ?”

CPU là các phần mạch điện tử phức tạp. Không đi vào cụ thể, chúng ta có thể nói rằng các phép toán trong CPU được phối hợp rất cẩn thận nếu không CPU có thể làm ra những kết quả sai lầm. Để đảm bảo rằng tất cả các hoạt động xảy ra vào một thời điểm là đúng, CPU 8086 sử dụng một tín hiệu được gọi là “hệ thống đồng hồ” (System clock).

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 03/03/2009 07:18:35 (+0700) | #29 | 171681
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
smilie smilie smilie

Phần 3.2.1: Hệ thống đồng hồ

Ở mức cơ bản nhất, hệ thống đồng hộ xử lý mọi sự đồng bộ hóa bên trong một hệ thống máy tính. Hệ thống đồng hồ là một tín hiệu điện trên bus điều khiển mà có sự luân phiên giữa không và một tại một chu kỳ tuần hoàn:




CPU là một ví dụ tốt cho một hệ thống logic đồng bộ phức tạp (xem các chương trước). Các cổng hệ thống đồng hồ của nhiều cổng logic mà tạo thành CPU sẽ cho phép nó hoạt động trong sự đồng bộ.

Tần số mà hệ thống đồng hồ luân phiên giữa không và một gọi là tần số hệ thống đồng hồ. Thời gian cần thiết cho hệ thống đồng hồ đổi từ không thành một và trở lại không là một chu kỳ đồng hồ. Một chu kỳ đầy đủ được gọi là một vòng đồng hồ. Trên phần lớn các hệ thống hiện đại, hệ thống đồng hồ đổi giữa không và một tại một tỷ lệ vượt hơn hàng triệu lần trên giây. Tần số đồng hồ đơn giản chỉ là số lượng các vòng đồng hồ xảy ra trên mỗi giây. Một con chip 80486 điển hình chạy với tốc đồ 66 triệu vòng mỗi giây. “Hertz” (Hz) là thuật ngữ kỹ thuật nghĩa là số vòng trên giây. Như vậy, con chip 80486 đã nói trên chạy với 66 triệu hert, hay 66 megahertz (MHz). Các tần số tiêu biểu cho các 8086 trong vùng từ 5 MHz tới 200 MHz và hơn thế nữa. Chú ý rằng một chu kỳ đồng hồ (thời gian cần thiết cho một vòng đồng hồ đầy đủ) là hàm thuận nghịch của tần số đồng hồ. Chẳng hạn, 1 MHz đồng hồ sẽ có một chu kỳ đồng hồ của một micro giây (1/1,000,000 của giây). Tương tự, một 10 MHz đồng hồ sẽ có một chu kỳ đồng hồ của một 100 nano giây (100 của một phần tỷ giây). Một CPU chạy với 50 MHz đồng hồ có một chu kỳ đồng hồ của 20 nano giây. Chú ý rằng chúng ta diễn tả các chu kỳ đồng hồ trong các phần triệu hoặc các phần tỉ của một giây.


Để đảm bảo tính đồng bộ, hầu hết các CPU bắt đầu các phép toán trên mọi sự hạ xuống (khi đồng hồ đi từ một tới không) hay tăng lên (khi đồng hồ đi từ không tới một). Hệ thống đồng hồ dùng phần lớn thời gian của nó tại không hay một và rất ít thời gian để chuyển đổi giữa hai số. Vì vậy đỉnh đồng hồ (clock edge) là một điểm đồng bộ hoàn hảo.

Vì tất cả các phép toán CPU được đồng bộ hóa xung quanh đồng hồ, nên CPU không thể thực hiện bất cứ yêu cầu nào nhanh hơn đồng hồ. Tuy nhiên, bởi vì một CPU đang chạy dưới một vài tần số đồng hồ không có nghĩa là nó thi hành nhiều phép toán mỗi giây. Nhiều phép toán cần nhiều vòng đồng hồ để hoàn thành vì vậy CPU thường xuyên thực hiện các phép toán tại một mức độ thấp hơn đáng kể.

smilie smilie smilie

Phần 3.2.2: Sự truy cập bộ nhớ và hệ đồng hồ

Truy cập bộ nhớ có lẽ là một hoạt thông dụng nhất của CPU. Truy cập bộ nhớ rõ ràng là một hoạt động đồng bộ hóa xung quanh hệ thống đồng hồ. Đó là, đọc một giá trị từ bộ nhớ hoặc viết một giá trị tới bộ nhớ không xảy ra thường xuyên hơn mỗi lần mỗi vòng đồng hồ. Thực vậy, trên các vi xử lý 8086, phải mất một vài chu kỳ đồng hồ để truy cập một địa chỉ nhớ. Việc truy cập bộ nhớ là số lần của các vòng đồng hồ mà hệ thống yêu cầu để truy cập một địa chỉ nhớ; đây là một giá trị quan trọng vì thời gian truy cập bộ nhớ dài hơn dẫn đến sự thực hiện thấp hơn.

Các vi xử lý 8086 khác nhau có các thời gian truy cập bộ nhớ khác nhau trong khoảng từ 1 tới 4 vòng đồng hồ. Ví dụ như, các CPU 8088 và 8086 yêu cầu bốn vòng đồng hồ để truy cập bộ nhớ, 80486 chỉ yêu cầu một. Vì vậy. 80486 sẽ thi hành các chương trình mà truy cập tới bộ nhớ nhanh hơn 8086, thậm chí khi chạy cùng một tần số đồng hồ.

Thời gian truy cập bộ nhớ là lượng thời gian giữa một phép toán bộ nhớ yêu cầu (đọc hoặc viết) và thời gian hoàn tất phép toán bộ nhớ. Trên 5 MHz CPU 8088/8086 thời gian truy cập bộ nhớ khoảng 800ns (nano giây). Trên 50 MHz 80486, thời gian truy cập bộ nhớ là ít hơn 20 ns. Chú ý rằng thời gian truy cập bộ nhớ cho 80486 nhanh hơn 40 lần so với 8088/8086. Đây là bởi vì tần số của 80486 gấp 10 lần và nó sử dụng một phần tư các chu kỳ (của 8088/8086) để truy cập bộ nhớ.

Khi đọc từ bộ nhớ, thời gian truy cập bộ nhớ là lượng thời gian từ điểm mà các CPU đặt một địa chỉ trên bus địa chỉ và đưa dữ liệu vào bus dữ liệu. Trên một CPU 80486 với một chu kỳ thời gian truy cập bộ nhớ, sự đọc được biểu diễn như hình dưới đây. Ghi dữ liệu cũng tương tự như vậy:







Chú ý rằng CPU không đợi cho bộ nhớ. Thời gian truy cập được định bởi tần số đồng hồ. Nếu hệ thống bộ nhớ không làm việc đủ nhanh, CPU sẽ đọc dữ liệu rác trên một thao tác đọc bộ nhớ và sẽ không lưu trữ chính xác dữ liệu trên một thao tác ghi bộ nhớ. Điều này chắc chắn sẽ làm cho hệ thống bị lỗi.


Các thiết bị bộ nhớ có các hiệu suất khác nhau, nhưng có hai điều chủ yếu là năng suất và tốc độ (thời gian truy cập). Thiết bị RAM điển hình (bộ nhớ truy cập ngẫu nhiên) có năng suất 4 (hay nhiều hơn) megabytes và tốc độ 50-100 ns. Bạn có thể mua các thiết bị lớn hơn hay nhanh hơn, nhưng chúng sẽ đắt hơn. Một hệ thống 33MHz 80486 sử dụng 70 ns các thiết bị nhớ

Đợi một chút! Tại 33 MHz có chu kỳ đồng hồ khoản 33 ns. Nhưng tại sao một nhà thiết kế hệ thống có thể sử dụng 70 ns bộ nhớ ? Câu hỏi là tình trạng chờ đợi
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 05/03/2009 10:05:34 (+0700) | #30 | 171957
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Đọc cái này xong tui chắc rằng bạn sẽ có thêm exp khi đi mua máy tính

smilie smilie smilie

Phần 3.2.3: Trạng thái đợi

Một trạng thái đợi không có gì nhiều hơn là thêm một vòng đồng hồ để cho một vài thiết bị có thời gian hoàn thành thao tác. Chẳng hạn, một hệ thống 50 MHz 80486 có chu kỳ đồng hồ là 20 ns. Điều này ý nói rằng bạn cần bộ nhớ 20 ns. Thực tế, tình huống này sẽ xấu hơn. Trong hầu hết tất cả các hệ thống máy tính đều có các mạch điện tử được thêm vào giữa CPU và bộ nhớ: bộ giải và bộ đệm logic. Các mạch điện tử được thêm vào này là sự hoãn lại trong hệ thống:




Trong biểu đồ này, hệ thống mất 10 ns để đệm và giải mã. Vì vậy nếu CPU cần dữ liệu trở lại trong 20 ns, bộ nhớ phải trả lời trong ít hơn 10 ns. Bạn có thể mua bộ nhớ 10 ns. Tuy nhiên, nó rất tốn kém, cồng kềnh, tiêu tốn nhiều sức mạnh và tỏa nhiều nhiệt. Đây là những thuộc tính xấu. Các siêu máy tính sử dụng loại bộ nhớ này. Tuy nhiên, các siêu máy tính có giá hàng triệu đô la, mất toàn bộ các phòng, yêu cầu đặc biệt làm mát, và phải có nguồn cung cấp năng lượng khổng lồ. Không phải là loại thứ mà bạn muốn ngồi vào bàn làm việc của bạn.

Nếu bộ nhớ giá tập thì nó sẽ không làm việc với một bộ vi xử lý nhanh, vậy làm thế nào các nhà sản xuất bán được máy tính ? Một phần của câu hỏi là trạng thái đợi. Ví dụ như, nếu bạn có vi xử lý 20 MHz với thời gian chu kỳ bộ nhớ là 50 ns và bạn mất 10 ns để đệm và giải mã, bạn sẽ cần bộ nhớ 40 ns. Điều gì sẽ xảy ra nếu bạn chỉ có bộ nhớ 80 ns trong hệ thống 20 MHz ? Thêm một trạng thái đợi để mở rộng chu kỳ nhớ lên tới 100 ns (hai vòng đồng hồ) sẽ giải quyết vấn đề này. Trừ 10 ns cho bộ giải mã và bộ đệm còn lại 90 ns. Vì thế, bộ nhớ 80 ns sẽ đáp ứng tốt trước khi CPU yêu cầu dữ liệu.

Hầu như mọi mục đích chung CPU trong thực thể là cung cấp một tín hiệu trên bus điều khiển để cho phép chèn các trạng thái đợi. Nói chúng, các mạch giải mã xác nhận dòng để hoãn lại thêm một chu kỳ đồng hồ, nếu cần thiết. Điều này cho bộ nhớ đầy đủ thời gian để truy cập, và hệ thống sẽ làm việc đúng:




Một vài trạng thái đợi là không đủ, Xét 80486 chạy ở 50 MHz. Một vòng chu kỳ bộ nhớ bình thường là ít hơn 20 ns. Vì vậy, ít hơn 10 ns sẽ sử dụng được sau khi trừ đi thời gian đệm và giải mã. Nếu bạn sử dụng bộ nhớ 60 ns trong hệ thống, thêm một trạng thái đợi sẽ không làm được. Mỗi trạng thái đợi cho bạn 20 ns, vì vậy một trạng thái đợi bạn sẽ cần bộ nhớ ít nhất 30 ns. Để làm việc với bộ nhớ 60 ns bạn sẽ cần thêm vào ba trạng thái đợi (trạng thái đợi 0 = 10 ns, trạng thái đợi một = 30 ns, trạng thái đợi 2 = 50 ns, và trạng thái đợi 3 = 70 ns).

Thêm một trạng thái đợi vào chu kỳ nhớ trên CPU 80486 làm gấp đôi lượng thời gian truy cập vào dữ liệu. Điều này làm giảm đi một nửa tốc độ truy cập bộ nhớ. Chạy với một trạng thái đọi trên mọi sự truy cập bộ nhớ gần như là mất đi một nửa tần số đồng hồ vi mạch. Bạn sẽ làm được công việc ít hơn trong cùng một lượng thời gian. Bạn đã có thể nhìn thấy các quảng cáo. "80386DX, 33 MHz, 8 MB RAM 0 trạng thái chờ đợi ...chỉ $1,000!” Nếu bạn xem xét chặt chẽ các đặc điểm kỹ thuật chi tiết bạn sẽ nhận thấy rằng các nhà sản xuất đang sử dụng bộ nhớ 80 ns. Bằng cách nào họ có thể xây dựng hệ thống chạy với 33 MHz và có không trạng thái đợi ? Dễ dàng. Họ nói láo.

Không có một cách nào mà 80386 có thể chạy tại 33 MHz, thi hành một chương trình tùy ý, mà không cần trạng thái đợi. Không thể làm được điều này. Tuy nhiên, nó sẽ rất phù hợp để thiết kế một hệ thống bộ nhớ dưới những hoàn cảnh nhất định, đặc biệt, trong trường hợp để tính toán mà không có tình trạng đợi ở một phần thời gian. Hầu hết các loại hình tiếp thị nếu hệ thống của họ tính toán mà không cần trạng thái đợi, thì họ có thể làm điều tự cho đó trong văn học của họ. Thực vậy, hầu hết các loại tiếp thị không có ý kiến gì về tình trạng đợi khác hơn là nó tồi tệ và có trạng thái đợi không là để kheo khoang khoác loác. Tuy nhiên, chúng ta không được kết tội việc thi hành chậm bởi vì các trạng thái đợi được thêm vào. Có một vài mánh khéo của các nhà thiết kế phần cứng có thể làm để đạt được trạng thái đợi không hầu hết các thời gian. Cái thông dụng nhất ở đây là sử dụng bộ nhớ đệm (cache (được phát âm “cash”)).

[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|