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
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 11/03/2009 08:43:23 (+0700) | #31 | 172784
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Mở đầu cho phần này tôi xin nói một điều cho các bạn dễ đọc hiểu:
Bộ nhớ đệm (cache memory) có tính năng thể hiện rất rõ mỗi khi bạn mở một chương trình nào đó. Khi bạn mở nó lần đầu thì lúc nào cũng lâu hơn là lần sau để biết nguyên nhân tại sao bạn hãy read những gì dưới đây smilie

Phần 3.2.4: Bộ nhớ đệm

Nếu bạn xem xét một chương trình điển hình (như nhiều nhà nghiên cứu có), bạn sẽ phát hiện ra rằng chúng có xu hướng truy cập vào cùng các địa chỉ nhớ lặp đi lặp lại nhiều lần Hơn nữa, bạn cũng có thể phát hiện ra rằng một chương trình thường xuyên truy cập các địa chỉ bộ nhớ kề nhau. Các tên kỹ thuật cho các hiện tượng này là thời gian địa phương chiếu và không gian địa phương tham chiếu. Khi đưa ra một không gian địa phương, thì một chương trình truy cập tới các địa chỉ bộ nhớ lân cận. Còn khi hiển thị thời gian địa phương tham chiếu một chương trình sẽ liên tục truy cập vào cùng địa chỉ nhớ trong một thời gian ngắn. Cả hai dạng thức vùng này cùng xảy ra ở các câu lệnh Pascal sau đây:

for n := 0 to 10 do
A [n] := 0;

Có hai lần xuất hiện cho mỗi dạng không gian và thời gian địa phương tham chiếu trong vòng lặp này. Hãy xét điều hiển nhiên đầu tiên.

Trong đoạn mã Pascal trên, chương trình tham chiếu vào biến i vài lần. Vòng lặp so sánh n với 10 để xem vòng lặp hoàn thành chưa. Nó cũng tăng n lên một tại đoạn trên vòng lặp. Câu lệnh gán cũng sử dụng n như một chỉ số mảng. Điều này cho thấy thời gian địa phương tham chiếu có trong hành động vì CPU truy cập vào n ba lần trong một thời gian ngắn.

Chương trình này cũng thể hiện không gian tham chiếu địa phương. Vòng lặp đặt 0 vào các phần tử của mảng bằng cách đặt 0 vào địa chỉ đầu tiên trong A, sau đó tới địa chỉ thứ hai trong A, và tiếp tục như vậy. Giả sử câu lệnh Pascal đó chứa các phần tử của A trong các địa chỉ nhớ liên tục nhau, thì mỗi vòng lặp sẽ truy cập tới các địa chỉ liền kề nhau.

Có một ví dụ phụ của thời gian và không gian địa phương tham chiếu trong ví dụ Pascal trên, mặc dù nó không được rõ ràng. Các lệnh máy tính cho hệ thống biết phải làm các nhiệm vụ xuất hiện trong bộ nhớ. Các lệnh này xuất hiện một cách tuần tự trong bộ nhớ – phần không gian địa phương. Máy tính cũng thi hành các lệnh đó liên tục cho mỗi vòng lặp – phần thời gian địa phương.

Nếu bạn xem xét sự thực hiện sơ lược của một chương trình điển hình, bạn sẽ phát hiện ra rằng chương trình này thực hiện thường ít hơn một nửa số lệnh. Thông thường, một chương trình điển hình có thể chỉ sử dụng 10-20% bộ nhớ được phân bổ cho nó. Tại một thời gian đã cho, một megabyte chương trình có thể chỉ cần truy cập 4 tới 8 kilobyte cho dữ liệu và mã chương trình . Vì vậy nếu bạn trả một số tiền lớn cho một bộ nhớ truy cập ngẫu nhiên (RAM) không trạng thái đợi đắt đỏ, thì bạn sẽ không được sử dụng nó tối đa tại bất cứ một thời điểm đã cho nào! Có phải nó sẽ không được tốt nếu bạn có thể mua một thanh RAM nhanh dung lượng nhỏ và gán lại các địa chỉ của nó như chương trình thi hành?

Đây chính xác là những gì bộ nhớ đệm làm cho bạn. Bộ nhớ đệm nằm giữa CPU và bộ nhớ chính. Nó là bộ nhớ dung lượng nhỏ rất nhanh (không trạng thái chờ). Không giống như bộ nhớ bình thường, các byte xuất hiện trong bộ đệm không được định địa chỉ. Thay vào đó, bộ nhớ đệm có thể gán lại địa chỉ cho đối tượng dữ liệu. Điều này cho phép hệ thống dữ được các giá trị truy cập gần đây trong bộ đệm. Các địa chỉ mà CPU không bao giờ truy cập hoặc không truy cập trong thời gian nào đó sẽ nằm lại trong bộ nhớ chính. Vì hầu hết các bộ nhớ truy cập là các biến được truy cập mới đây (hoặc các địa chỉ gần một địa chỉ mới được truy cập), dữ liệu thông thường xuất hiện trong bộ nhớ đệm.

Bộ nhớ đệm là không hoàn hảo. Mặc dù một chương trình có thể dùng nhiều thời gian để thi hành mã ở một nơi, nhưng cuối cùng nó sẽ gọi một thủ tục hay lang thang đến một vài phần của đoạn mã ngoài bộ nhớ đệm. Trong sự việc như vậy CPU phải đi vào bộ nhớ chính để lấy dữ liệu. Vì bộ nhớ chính là chậm, nên điều này sẽ yêu cầu chèn thêm tình trạng đợi.

Một công việc bộ đệm thành công (cache hit) xuất hiện khi nào CPU truy cập và tìm dữ liệu trong bộ đệm. Trong những trường hợp như vậy CPU có thể thường truy cập dữ liệu với không trạng thái chờ. Một công việc bộ đệm bị lỡ (cache miss) nếu CPU truy cập bộ nhớ và dữ liệu không có ở trong bộ đệm hiện tại. Sau đó CPU phải đọc dữ liệu từ bộ nhớ chính, và chịu một sự thực hiện hao phí. Để tận dụng được sự thuận lợi của địa phương tham chiếu, CPU sao chép dữ liệu vào trong bộ đệm bất cứ khi nào nó truy cập một địa chỉ không trong bộ đệm hiện tại. Một khi hệ thống có khả năng truy cập cùng một địa chỉ trong thời gian ngắn, hệ thống sẽ tiết kiệm được các tình trạng đợi bằng việc nhớ dữ liệu đó trong bộ đệm.

Như đã miêu tả ở trên, bộ nhớ đệm xử lý thời gian của sự truy cập bộ nhớ, nhưng không phải không gian. Các địa chỉ bộ nhớ đệm khi bạn truy cập vào chúng sẽ không làm tăng tốc chương trình của bạn nếu bạn cứ liên tục truy cập vào những địa chỉ liên tiếp (không gian tham chiếu địa phương). Để giải quyết vấn đề này, hầu hết các hệ thống đệm sẽ đọc một vài byte liên tiếp từ bộ nhớ khi cache miss. 80486, chẳng hạn, đọc 16 byte tại một lệnh điều khiển vào lúc cache miss. Nếu bạn đọc 16 bytes, tại sao đọc chúng trong các khối hơn là trong khi bạn cần chúng? Khi nó được gọi ra hầu hết các chip bộ nhớ có sẵn ngày nay có chế độ đặc biệt cho phép bạn nhanh chóng truy cập vào các địa chỉ nhớ liền nhau trên chip. Bộ đệm khai thác khả năng này để giảm tối thiểu lượng trung bình trạng thái đợi cần thiết để truy cập bộ nhớ.

Nếu bạn viết một chương trình sử dụng bộ nhớ truy cập ngẫu nhiên, thì sử dụng bộ đệm có thể làm bạn chậm xuống. Đọc 16 bytes trên mỗi cache miss của bộ đệm là một cái giá rất đắt nếu bạn chỉ truy cập một vài byte trong dòng đệm tương đương. Tuy nhiên, hệ thống bộ nhớ đệm làm việc khá tốt.

Không ngạc nhiên gì khi tỉ lệ của các cache hit thành cache miss tăng lên với cỡ của hệ bộ nhớ đệm. Chip 80486, chẳng hạn, có 8,192 byte trên chip bộ đệm. Intel cho là tỉ lệ 80-95% đạt được của cache hit với bộ đệm này (điều này nghĩa là 80-95% thời gian CPU tìm dữ liệu trong bộ đệm). Nghe có vẻ rất ấn tượng. Tuy nhiên, nếu bạn sử dụng với các số lượng mẫu nhỏ, bạn sẽ khám phá ra rằng nó không hoàn toàn ấn tượng. Giả sử chúng ta lấy con số 80%. Sau đó một cái ở ngoài của mọi năm lần truy cập bộ nhớ, trung bình, sẽ không được nằm trong bộ đệm. Nếu bạn có vi xử lý 50 MHz và bộ nhớ 90 ns thời gian truy cập, bốn cái ở ngoài của năm lần truy cập bộ nhớ chỉ yêu cầu một vòng đồng hồ (vì chúng ở trong bộ đệm) và 15 cái sẽ yêu cầu khoảng 10 trạng thái đợismilie. Nói chung, hệ thống sẽ yêu cầu 15 vòng đồng hồ để truy cập 5 địa chỉ nhớ, hay trung bình ba vòng đồng hồ mỗi lần truy cập. Đó là sự tương đương để hai trạng thái đợi được thêm vào cho mỗi lần truy cập bộ nhớ. Có phải bây giờ bạn tin rằng máy bạn có thể chạy với không trạng thái chờ?

Có một vài cách để cải thiện tình hình. Đầu tiên, bạn có thể thêm nhiều hơn bộ nhớ đệm. Điều này làm nâng cao tỉ lệ công việc thành công bộ đệm, giảm đi số lượng tình trạng đợi. Chẳng hạn, tăng tỉ lệ từ 80% đến 90% cho phép bạn truy cập 10 địa chỉ bộ nhớ trong 20 vòng. Điều này sẽ làm giảm đi số lượng trung bình của trạng thái đợi cho mỗi lần truy cập bộ nhớ vào một trong trạng thái đợi – một cải tiến đáng kể. Nhưng bạn không thể kéo con chip 80486 về một bên và hàn nhiều bộ đệm vào chip. Tuy nhiên, CPU 80586/Pentium có một bộ nhớ đệm lớn hơn đáng kể so với 80486 và các hoạt động ít tình trạng đợi hơn.

Một cách khác để nâng cao hiệu quả thực hiện là xây dựng bộ nhớ đệm hai-mức. Nhiều hệ thống 80486 làm việc kiểu như vậy. Mức đầu tiên là bộ đệm 8,192 byte trên chip(on-chip). Mức tiếp theo, giữa bộ đệm trên chip và bộ nhớ chính, là bộ đệm thứ nhì được xây dựng trên bảng mạch hệ thống máy tính:





Bộ đệm thứ nhì điển hình chứa đựng bất cứ cái gì từ 32,768 byte tới 1 megabyte của bộ nhớ, Cỡ thông dụng trên hệ thống PC là 65,536 và 262,144 byte bộ đệm. Bạn có thể hỏi “Tại sao lại phiền lòng với bộ đệm 2-mức? Tại sao không sử dụng 262,144 byte bộ đệm để bắt đầu?”. Bộ đệm thứ hai không thực hiện tại không trạng thái đợi. Mạch điện tử để hỗ trợ 262,144 byte cho 10 ns bộ nhớ (tổng cộng 20 ns thời gian truy cập) sẽ rất đắt. Vì vậy hầu hết các nhà thiết kế hệ thống sử dụng bộ nhớ chậm hơn yêu cầu một hoặc hai trạng thái đợi. Điều này vẫn nhanh hơn so với bộ nhớ chính. Kết hợp với bộ đệm trên chip, bạn có thể đạt được hiệu suất tốt hơn từ hệ thống.

Xét ví dụ trước với tỉ lệ 80%. Nếu bộ đệm thứ hai yêu cầu hai vòng cho mỗi lần truy cập bộ nhớ và ba vòng cho lần truy cập đầu tiên, khi một cache miss trên bộ đệm on-chip sẽ yêu cầu tổng cộng sáu vòng. Tất cả đã nói lên, trung bình hiệu suất hệ thống sẽ là 2 chu kỳ đồng hồ mỗi lần truy cập bộ nhớ. Khá nhanh hơn một chút so với ba yêu cầu bởi hệ thống ngoài bộ đệm thứ hai. Hơn nữa, bộ đệm thứ hai có thể cập nhật những giá trị của nó song song với CPU. Vì vậy số lượng cache miss bộ đệm (ảnh hưởng tới hiệu suất CPU) sẽ giảm xuống.

Bạn có thể nghĩ “Cho đến lúc này mọi cơ sở đều thú vị, nhưng phải làm gì với một chương trình?”. Bằng cách viết chương trình của bạn cẩn thận để thuận lợi theo cách mà hệ thống bộ đệm làm việc, bạn có thể nâng cao được hiệu suất chương trình của bạn. Bằng cách sắp xếp các biến bạn thường sử dụng lại với nhau trong cùng một dòng bộ đệm, bạn có thể làm cho hệ thống bộ đệm đọc các biến này như một nhóm, và thêm một vài trạng thái chờ trên mỗi lần truy cập.

Nếu bạn sắp xếp chương trình của bạn có xu hướng cùng thực hiện một chuỗi lệnh liện tục, nó sẽ có một mức độ cao của thời gian địa phương tham chiếu và sẽ, vì vậy, sẽ thi hành nhanh hơn.

Chú thích smilie:Mười trạng thái chờ được tính như sau: năm vòng đồng hồ để đọc bốn bytes đầu tiên (10+20+20+20+20=90). Tuy nhiên, bộ đệm luôn luôn đọc 16 byte liên tiếp. Hầu hết các hệ thống nhớ cho bạn đọc các địa chỉ liên tiếp trong khoản 40 ns sau lần truy cập đầu tiên. Vì vậy, 80486 sẽ yêu cầu thêm 16 vòng đồng hồ để đọc ba double word còn lại. Vậy có tổng cộng 11 hoặc 10 trạng thái đợi.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 13/03/2009 09:21:53 (+0700) | #32 | 173037
[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.3.1:Thanh ghi CPU

Các thanh ghi CPU là các địa chỉ bộ nhớ đặc biệt được xây dựng từ flip-flop. Chúng không phải là một phần của bộ nhớ chính; CPU thực hiện chúng trên chip(on-chip). Các thành viên khác nhau của họ 8086 có các cỡ thanh ghi khác nhau. 886, 8286, 8486, và 8686 (và các đời sau x86) các CPU có đúng 4 thanh ghi, tất cả đều 16 bit. Tất cả các phép toán số học và thao tác địa chỉ đều xảy ra trong các thanh ghi CPU.

Bởi vì vi mạch x86 chỉ có vài thanh ghi, nên chúng ra sẽ cho mỗi thanh ghi một cái tên và quy cho nó bằng tên hơn là địa chỉ của nó. Các tên cho các thanh ghi x86 là

AX –Thanh ghi tích lũy
BX –Thanh ghi nền
CX –Thanh ghi bộ đếm
DX –Thanh ghi dữ liệu

Bên cạnh những thanh ghi trên, cái mà rõ ràng với lập trình viên, thì vi xử lý x86 cũng có những thanh ghi con trỏ chứa các địa chỉ của các lệnh kế tiếp để thi hành. Cũng có các thanh ghi cờ để biểu thị kết quả của sự so sánh. Các thanh ghi cờ sẽ ghi nhớ nếu một giá trị bé hơn, bằng, hoặc lớn hơn giá trị khác.

Bởi vì các thanh ghi ở trên chip và được điểu khiển đặc biệt bởi CPU, nên chúng nhanh hơn nhiều so với bộ nhớ. Truy cập một địa chỉ bộ nhớ yêu cầu một hoặc nhiều vòng đồng hồ. Truy cập dữ liệu trong thanh ghi thường mất không vòng đồng hồ. Vì vậy, bạn nên cố gắng giữ các biến trong thanh ghi. Thanh ghi là rất nhỏ và hầu hết các thanh ghi có các mục đích đặc biệt là hạn định chúng sử dụng các biến, nhưng chúng vẫn là nơi tuyệt vời để lưu trữ các dữ liệu tạm thời.

smilie smilie smilie

Phần 3.3.2: Bộ luận lý số học & đơn vị logic

Bộ luận lý số học và đơn vị logic (ALU) là nơi mà hầu hết các hoạt động diễn ra trong CPU. Chẳng hạn, nếu bạn muốn cộng một giá trị năm vào thanh ghi AX, CPU sẽ làm như sau:
-Sao chép giá trị từ AX vào ALU
-Gửi giá trị 5 vào ALU
-Chỉ thị cho ALU cộng hai giá trị đó với nhau

smilie smilie smilie

Phần 3.3.3:Đơn vị giao tiếp bus

Đơn vị giao tiếp bus (bus interface unit) BIU có nhiệm vụ điều khiển các địa chỉ và bus dữ liệu khi truy cập vào bộ nhớ chính. Nếu hiện tại một bộ đệm có mặt trên CPU thì BIU cũng có trách nhiệm điều khiển việc truy cập dữ liệu trong bộ đệm.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 14/03/2009 10:02:25 (+0700) | #33 | 173162
[Avatar]
change_my_way2010
Member

[Minus]    0    [Plus]
Joined: 12/11/2007 09:28:55
Messages: 48
Offline
[Profile] [PM]
Phần hệ thống đồng hồ:
Như vậy, con chip 80486 đã nói trên chạy với 66 triệu hert, hay 66 triệu 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 

Hình như có nhầm lẫn phải không bạn.
PS:Cám ơn nhiều nhé bạn,đang cần nghiên cứu chỗ này,đỡ mất công tìm kiếm.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 14/03/2009 16:18:39 (+0700) | #34 | 173190
[Avatar]
U^U
Member

[Minus]    0    [Plus]
Joined: 07/07/2008 16:59:00
Messages: 39
Location: Ghost
Offline
[Profile] [PM]
Đã fix. Thank bạn đã nhắc nhở.

Phần 3.3.4:Đơn vị điều khiển và tập lệnh

3.3.4 The Control Unit and Instruction Sets
Một câu hỏi đặt ra tại thời điểm này là “Bằng cách nào một CPU có thể thực hiện được chính xác các công việc được chỉ định?” Điều này được hoàn thành bằng cách đưa ra cho CPU một tập hợp các lệnh, hay các chỉ thị, để làm việc. Hãy nhớ rằng CPU được xây dựng bằng các vi mạch sử dụng các cổng logic để thi hành những lệnh này. Để có thể giữ được số lượng các cổng logic cho một tập nhỏ hợp lý (10 hoặc hàng trăm nghìn), các nhà thiết kế CPU nhất thiết phải hạn chế số lượng và tính phức tạp của các câu lệnh mà CPU nhận. Tập hợp nhỏ của các lệnh này gọi là tập lệnh máy CPU.

Các chương trình trong các hệ thống máy tính trước đây (trước Von Neumann) thường được kiểm soát bằng mạch điện tử. Đó là, sự đi dây máy tính xác định vấn đề mà máy tính sẽ giải quyết. Nhưng có điều là phải mắc lại mạch (rewire) để thay đổi chương trình. Một nhiệm vụ khó khăn. Sự tiến bộ tiếp theo trong thiết kế máy tính là có thể lập trình được hệ thống máy tính, điều đó cho phép một lập trình viên máy tính dễ dàng “rewire” hệ thống máy tính sử dụng các lỗ tuần tự và các chốt điện. Một chương trình máy tính bao gồm tập hợp các hàng của lỗ (sockets), mỗi hàng biểu diễn một phép tính trong suốt thời gian thi hành chương trình. Lập trình viên có thể lựa chọn một vài chỉ thị bằng cách chốt một dây trong lỗ đặc biệt cho chỉ thị mong muốn:




Đương nhiên, một khó khăn lớn với sơ đồ này là số lượng các chỉ thị phù hợp được giới hạn khắt khe bởi số lượng các socket có thể đặt trên mỗi hàng về mặt vật lý. Tuy nhiên, các nhà thiết kế CPU nhanh chóng phát hiện ra rằng với một số lượng nhỏ mạch logic được thêm vào, thì chúng có thể giảm đi số lượng các socket được yêu cầu từ n lỗ cho n chỉ thị thành log2(n) lỗ cho n chỉ thị. Họ đã làm bằng cách gán một mã số cho mỗi lệnh và mã hóa các chỉ thị như số nhị phân sử dụng log2(n) lỗ:




Điều được thêm vào này yêu cầu 8 hàm logic để giải mã các bit A, B, C từ bảng điều khiển, nhưng các mạch phụ đáng giá cho chi phí vì nó giảm được số lượng các sọcket phải được sử dụng liên tục cho mỗi lệnh.




Đương nhiên, nhiều chỉ thị CPU không đứng một mình. Chẳng hạn, lệnh di chuyển là một lệnh di chuyển dữ liệu từ một địa chỉ trong máy tính tới một địa chỉ khác (ví dụ, từ một thanh ghi tới một thanh ghi khác). Vì vậy, lệnh chuyển yêu cầu hai toán hạng: một toán hạng nguồn và một toán hạng đích. Các nhà thiết kế CPU thường mã hóa các toán hạng đích và nguồn như một phần của lệnh máy, các socket nào đó tương ứng với toán hạng nguồn và các socket nào đó tương ứng với toán hạng. Hình trên cho thấy có một sự kết hợp giữa các socket để xử lý công việc này. Lệnh di chuyển (move) sẽ chuyển dữ liệu từ thanh ghi nguồn tới thanh ghi đích, lệnh cộng (add) sẽ cộng giá trị thanh ghi nguồn vào giá trị thanh ghi đích,...

Một trong những tiến bộ chính trong thiết kế máy vi tính mà VNA cung cấp là khái niệm về một chương trình được lưu trữ. Một vấn đề lớn với phương thức bảng mạch chương trình là số lượng các bước chương trình (các lệnh máy) bị giới hạn bởi số dòng của socket có sẵn trên máy. John Von Neumann và các hệ máy tính khác chấp nhận mối quan hệ giữa socket trên bảng mạch và bit trong bộ nhớ; chúng hiểu chúng có thể lưu trữ các nhị phân tương đương của chương trình máy trong bộ nhớ và lấy mỗi chương trình từ bộ nhớ, đọc nó trong một thanh ghi giải mã đặc biệt được nối trực tiếp tới bộ mạch giải mã lệnh của CPU

Mánh khéo, đương nhiên, đã được thêm vào nhiều hơn vào mạch cho CPU. Mạch này, đơn vị điều khiển (CU), lấy mã chỉ thị (như là các mã phép toán hoặc mã lệnh) từ bộ nhớ và chuyển chúng vào thanh ghi giải mã lệnh. Đơn vị điều khiển chứa một thanh ghi đặc biệt, con trỏ lệnh chứa địa chỉ của lệnh có thể thực hiện. Đơn vị điều khiển lấy các mã lệnh này từ bộ nhớ và đặt chúng và thanh ghi giải mã để thi hành. Sau khi thi hành lệnh, đơn vị điều khiển tăng con trỏ lệnh và lấy lệnh tiếp theo từ bộ nhớ để thi hành và tiếp tục như vậy.

Khi thiết kế một tập lệnh, các nhà thiết kế CPU thường chọn các mã lệnh có độ dài bit là bội số của 8 vì vậy CPU có thể dễ dàng lấy hoàn toàn lệnh từ bộ nhớ. Mục tiêu của các nhà thiết kế CPU là chỉ định một số các bit thích hợp tới các lớp lệnh nền (di chuyển, cộng, trừ, …) và các dải toán hạng. Chọn thêm bit cho lệnh nền cho bạn nhiều lệnh hơn, chọn các bit thêm vào cho dải toán hạng cho bạn chọn số lớn hơn cho toán hạng (ví dụ địa chỉ bộ nhớ hoặc thanh ghi). Có những sự bổ sung phức tạp. Vài chỉ thị chỉ có một toán hạng hoặc chúng không có một toán hạng nào cả. Thay vì lãng phí bit cho các điều này, các nhà thiết kế CPU thường xuyên sử dụng các dải bit này để mã hóa mã lệnh thêm vào, một lần nữa với một vài mạch thêm vào. Họ Intel 8086 đưa điều này tới giới hạn với các chỉ thị trong khoảng từ một tới mười byte độ dài. Vì điều này không quá khó để xử lý với giai đoạn đầu, các CPU x86 sẽ sử dụng khác nhau, đơn giản hơn nhiều, sơ đồ mã hóa.
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 15/03/2009 14:43:31 (+0700) | #35 | 173272
[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.3.5: Tập lệnh của CPU x86

CPU x86 cung cấp 20 lớp lệnh cơ sở. 7 cho các lệnh có 2 toán hạng, 8 cho các lệnh chỉ có một toán hạng, và 5 cho các lệnh không có toán hạng nào cả. Các lệnh là mov, add, sub, cmp, and, or, not, je, jne, jb, jbe, ja, jae, jmp, brk, iret, halt, get, và put. Đoạn sau đây miêu tả cách làm việc mỗi lệnh.

Lệnh mov thực tế là hai lớp lệnh kết hợp vào cùng một lệnh. Hai dạng của lệnh mov được đưa ra dưới dạng sau:

Code:
mov reg, reg/memory/constant
mov memory, reg

Ở đây reg là một trong số các thanh ghi ax, bx, cx, hoặc dx; constant là hằng số (sử dụng ký pháp hexa), và memory là toán hạng được định bởi một địa chỉ nhớ. Phần tới miêu tả các dạng toán hạng bộ nhớ phù hợp có thể dùng. Toán hạng “ reg/memory/constant” cho bạn biết rằng các toán hạng này có thể là một thanh ghi, địa chỉ nhớ, hoặc một hằng số.

Các lệnh số học và logic đưa ra dưới dạng sau:

Code:
add reg, reg/memory/constant
sub reg, reg/memory/constant
cmp reg, reg/memory/constant
and reg, reg/memory/constant
or reg, reg/memory/constant
not reg/memory

Lệnh add cộng giá trị của toán hạng thứ hai với toán hạng thứ nhất (thanh ghi), để lại tổng trong toán hạng thứ nhất. Lệnh sub trừ giá trị của toán hạng thứ hai tới toán hạng thứ nhất, cho kết quả trong toán hạng thứ nhất. Lệnh cmp so sánh toán hạng thứ nhất và toán hạng thứ hai và lưu lại kết quả của phép so sánh cho việc sử dụng làm điều kiện cho lệnh nhảy. Lệnh and và or thực hiện các phép toán logic bit trên hai toán hạng và chứa kết quả ở toán hạng đầu tiên. Lệnh not đảo ngược các bit trên toán hạng bộ nhớ hoặc thanh ghi.

Các lệnh chuyển điểu khiển (control transfer) ngắt tính tuần tự của sự thực hiện của các lệnh trong bộ nhớ và chuyển điểu khiển tới vài điểm khác trong bộ nhớ vô điều kiện, hoặc sau khi kiểm tra kết quả của lệnh cmp. Các lệnh này bao gồm:

Code:
ja       dest – Nhảy nếu lớn hơn
 jae     dest – Nhảy nếu lớn hơn hoặc bằng 
 jb       dest – Nhảy nếu bé hơn
 jbe     dest – Nhảy nếu bé hơn hoặc bằng
 je       dest – Nhảy nếu bằng
 jne     dest – Nhảy nếu không bằng 
 jmp    dest – Nhảy không điểu kiện
 iret            – Trở lại từ một điểm ngắt

Sáu lệnh đầu tiên trong lớp này cho bạn kiểm tra kết quả của lệnh cmp trước lớn hơn, lớn hơn hoặc bằng, bé hơn, bé hơn hoặc bằng, bằng, hoặc không bằng. Ví dụ như, nếu bạn so sánh các thanh ghi ax và bx với lệnh cmp và thi hành lệnh ja, CPU x86 sẽ nhảy tới địa chỉ đích nếu ax lớn hơn bx. Nếu ax không lớn hơn bx, thì sự điều khiển sẽ đi vào câu lệnh tiếp theo trong chương trình. Lệnh nhảy không điều kiện jmp chuyển điều khiển tới lệnh tại địa chỉ nguông. Lệnh iret trả lại điều khiển từ một thủ tục phục vụ ngắt, chúng ta sẽ bàn luận điều này sau.

Các lệnh get và put cho bạn đọc và viết các giá trị nguyên. Get sẽ dừng và nhắc người sử dụng cho một giá trị hexa và sau đó chứa giá trị vào thanh ghi ax. Put hiển thị (trong hệ hexa) giá trị của thanh ghi ax.

Các câu lệnh còn lại không yêu cầu toán hạng nào, chúng là halt và brk. Halt chấm dứt chương trình thức hiện và brk dừng chương trình lại trong một trạng thái mà nó có thể được khởi động lại. Vi xử lý x86 yêu cầu một đoạn mã máy riêng biệt cho mỗi lệnh khác nhau, không chỉ các lớp lệnh. Mặc dù “mov ax,bx” và “mov ax,cx” thuộc cùng một lớp, nhưng chúng phải có các đoạn mã máy khác nhau nếu CPU phân biệt chúng. Tuy nhiên, trước khi xem xét các mã máy phù hợp, thì có lẽ nó sẽ là một ý kiến tốt để học về tất cả các toán hạng thích hợp cho các lệnh đó.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 19/03/2009 15:15:46 (+0700) | #36 | 173778
[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.3.6: Các hình thức địa chỉ trên x86

Các lệnh x86 sử dụng 5 loại toán hạng khác nhau: các thanh ghi, các hằng số, và ba sơ đồ địa chỉ bộ nhớ. Mỗi dạng được gọi là một hình thức địa chỉ. Vi xử lý x86 hỗ trợ hình thức địa chỉ thanh ghi, hình thức địa chỉ tức thời, hình thức địa chỉ gián tiếp, hình thức địa chỉ chỉ số, và hình thức địa chỉ trực tiếp. Những đoạn sau đây giải thích cho mỗi hình thức này.

Các toán hạng thanh ghi là cái dễ dàng hiểu nhất. Xét dạng của lệnh mov sau đây:

mov ax, ax
mov ax, bx
mov ax, cx
mov ax, dx


Lệnh đầu tiên hoàn toàn không có gì. Nó sao chép giá trị từ thanh ghi ax trở lại vào thanh ghi ax. Ba lệnh còn lại sao chép dữ liệu của bx, cx, và dx vào ax. Chú ý rằng giá trị ban đầu của bx, cx,dx vẫn giữ nguyên. Toán hạng đầu tiên (đích) không giới hạn đối với ax, bạn có thể chuyển giá trị vào các thanh ghi còn lại khác.

Hằng số cũng tương đối dễ dàng giải quyết. Xét các lệnh sau:

mov ax, 25
mov bx, 195
mov cx, 2056
mov dx, 1000


Các câu lệnh này khá đơn giản; chúng được nạp vào các thanh ghi tương ứng với quy định hằng số của hệ hexa

Có ba hình thức địa chỉ xử lý với sự truy cập dữ liệu trong bộ nhớ. Các hình thức địa chỉ này được đưa ra dưới dạng sau:


mov ax, [1000]
mov ax, [bx]
mov ax, [1000+bx]


Câu lệnh đầu tiên ở trên sử dụng hình thức địa chỉ trực tiếp để nạp vào ax với 16 bit giá trị được chứa trong bộ nhớ bắt đầu tại địa chỉ 1000 hex.

Câu lệnh ax,[bx] nạp vào ax từ địa chỉ bộ nhớ được định bởi nội dung của thanh ghi bx. Đây là hình thức địa chỉ gián tiếp. Thay vì sử dụng giá trị trong bx, câu lệnh này truy cập vào địa chỉ bộ nhớ của địa chỉ trong bx. Chú ý hai câu lệnh sau:

mov bx, 1000
mov ax, [bx]

là tương đương chỉ với một câu lệnh

mov ax, [1000]

Đương nhiên, câu thứ hai được ưa chuộng hơn. Tuy nhiên, có nhiều trường hợp sử dụng gián tiếp nhanh hơn, ngắn hơn và tốt hơn. Chúng ta sẽ thấy được một vài ví dụ của điều này khi xem xét từng cái trong họ x86 về sau.

Hình thức địa chỉ cuối là hình thức địa chỉ chỉ số. Một ví dụ của hình thức địa chỉ này là:

mov ax, [1000+bx]


Câu lệnh này cộng nội dung của bx với 1000 để cho ra địa chỉ của giá trị bộ nhớ để lấy vào ax. Câu lệnh này rất hữu dụng khi truy cập các phần tử của mảng, các bản ghi, và cấu trúc dữ liệu khác.
[size=+1][color=cyan][i]
[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 24/03/2009 08:53:39 (+0700) | #37 | 174411
[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.37: Mã hóa các lệnh x86

Mặc dù chúng ta có thể tùy ý gán những mã máy tới mỗi lệnh trong toàn bộ lệnh x86, nhưng nhớ rằng CPU sử dụng mạch logic để giải mã các mã máy và thực hiện các hành động thích hợp trên chúng. Một mã máy CPU điển hình sử dụng một lượng bit nào đó trong mã máy để lớp lệnh (ví dụ, mov, add, sub), và một lượng bit nào đó để mã hóa mỗi toán hạng. Vài hệ thống (ví dụ, CISC, hoặc Complex Instruction Set Computers) mã hóa các trường này trong một cách rất phức tạp cho ra các lệnh ngắn gọn. Các hệ thống khác (ví dụ, RISC, hay Reduced Instruction Set Computers) mã hóa các mã máy rất đơn giản ngay cả khi nếu nó lãng phí một vài bit trong mã máy hoặc giới hạn số lượng các phép toán. Họ 8086 Intel là hệ thống CISC và có một trong hầu hết các mã máy phức tạp giải mã các biểu đồ đã được thiết lập sẵn. Toàn bộ mục đích cho các vi mạch X86 giả định là để trình bày các khái niệm về lệnh mã hóa mà không có sự phức tạp của họ x86, trong khi vẫn miêu tả được sự mã hóa CISC.

Một lệnh x86 điển hình dùng dạng như sau:




Lệnh cơ bản có một hoặc ba byte độ dài. Lệnh mã máy bao gồm một byte đơn chứa ba trường. Trường đầu tiên, ba bit H.O, định nghĩa lớp lệnh. Điều này cung cấp tám tổ hợp. Bạn có thể nhớ lại, là có 20 lớp lệnh; chúng ta không thể mã hóa 20 lớp lệnh với ba bit, vì vậy chúng ta sẽ phải thêm một vài mánh khéo để điểu khiển các lớp khác. Như bạn có thể thấy trong hình trên, mã máy (opcode) cơ bản mã hóa các lệnh mov (hai lớp, ở đây trường rr chỉ định đích,và trường mmm cũng chỉ định điểm đích), add, sub, cmp, and, và lệnh or. Có một lớp thêm vào: specical. Lớp lệnh special cung cấp một cơ chế mà cho phép chúng ta mở rộng số lượng các lớp lệnh có sẵn, chúng ta sẽ sớm trở lại với lớp này.

Để xác định một mã máy của lệnh, bạn chỉ cần lựa chọn các bit phù hợp cho các trường iii, rr, và mmm. Ví dụ như, để mã hóa lệnh mov ax, bx bạn sẽ chọn iii=110 (mov reg, reg), rr=00 (ax), và mmm=001 (bx). Điều này cho ra lệnh một byte 11000001 hay 0C0h.

Một vài lệnh x86 yêu cầu nhiều hơn một byte. Ví dụ, lệnh mov ax, [1000] nạp vào thanh ghi ax từ bộ nhớ địa chỉ 1000. Sự mã hóa cho mã máy là 11000110 hay 0C6h. Tuy nhiên, sự mã hóa cho mã máy của mov ax, [2000] cũng là 0C6h. Rõ ràng hai lệnh này làm những điều khác nhau, một cái nạp thanh ghi ax từ địa chỉ bộ nhớ 1000 trong khi cái còn lại nạp thanh ghi ax từ địa chỉ bộ nhớ 2000. Để mã hóa một địa chỉ cho các hình thức địa chỉ [xxxx] hoặc [xxxx+bx], hoặc để mã hóa các hằng cho các hình thức địa chỉ trực tiếp, bạn phải làm theo sau các mã máy với địa chỉ 16 bit hoặc hằng, với byte L.O. trực tiếp theo sau mã máy trong bộ nhớ và byte H.O. sau đó xác định hình thức địa chỉ. Vì vậy ba byte để mã hóa cho lệnh mov ax, [1000] sẽ là 06Ch, 00h, 10h và ba byte mã hóa cho mov ax, [2000] sẽ là 0C6h, 00h, 20h. Các mã máy đặc biệt cho phép CPU x86 mở rộng tập hợp các lệnh có sẵn. Mã máy này điều khiển một vài lệnh không và một toán hạng như các hình dưới đây:







Có 4 lớp lệnh một toán hạng. Mã hóa đầu tiên (00) tiếp tục mở rộng cho tập lệnh với các lệnh không toán hạng. Mã máy thứ hai cũng là sự mở rộng một mã máy cho bởi tất cả các lệnh nhảy của x86:




Mã máy thứ ba là lệnh not. Đây là phép toán logic bit not đảo ngược tất cả các bit của thanh ghi đích hoặc toán hạng bộ nhớ. Mã máy thứ tư hiện thời không được gán gì cả. Bất kỳ sự cố gắng thực hiện mã máy này sẽ bị tạm dừng bộ xử lý lại với một vài lỗi không hợp lệ. Các nhà thiết kế CPU thường đặt các mã máy không được gán như thế này để mở rộng tập lệnh vào một ngày tương lai (như Intel làm khi chuyển từ vi mạch 80286 thành 80386).

Có 7 lệnh nhảy trong tập lệnh x86. Tất cả chúng được đưa ra dưới dạng sau:

jxx address

Lệnh jmp sao chép 16 bit giá trị trực tiếp (địa chỉ) theo sau mã máy vào trong thanh ghi IP. Sau đó, CPU sẽ lấy lệnh kế tiếp từ địa chỉ đích này;thực tế, chương trình “nhảy” từ điểm của lệnh jmp tới lệnh tại địa chỉ đích.

Lệnh jmp là một ví dụ cho lệnh nhảy không điều kiện. Nó luôn luôn chuyển điều khiển tới địa chỉ đích. Sáu lệnh còn lại là lệnh nhảy có điều kiện. Chúng kiểm tra một vài điều điều kiện và nhảy nếu điều kiện đúng; chúng sẽ tới lệnh tiếp theo nếu điều kiện sai. Sáu lệnh này, ja, jae, jb, jbe, je, và jne cho bạn kiểm tra lớn hơn, lớn hơn hoặc bằng, bé hơn, bé hơn hoặc bằng, bằng, và không bằng. Bạn sẽ thi hành bình thường trực tiếp các lệnh này sau một lệnh cmp.

[Up] [Print Copy]
  [Question]   Re: ASM cho newbie (dich tu` Art of Assembly) 29/03/2009 02:06:44 (+0700) | #38 | 175115
[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.3.8: Từng bước thi hành lệnh

Các CPU 8086 không hoàn thành một lệnh trong một vòng đồng hồ. CPU thực hiện một vài bước cho mỗi lệnh. Chẳng hạn, CPU đưa ra các lệnh sau để thi hành chỉ thị mov reg, reg/memory/constant:

-Lấy byte lệnh từ bộ nhớ
-Nạp thanh ghi ip tới điểm byte tiếp theo
-Giải mã lệnh để xem những gì nó làm
-Nếu cần thiết, thì lấy một chỉ thị toán hạng 16 bit từ bộ nhớ
-Nếu cần thiết, thì cập nhật ip ở bên ngoài toán hạng
-Tính địa chỉ của toán hạng, nếu được yêu cầu (ví dụ, bx+xxxx)
-Lấy toán hạng
-Chứa giá trị được lấy vào thanh ghi nguồn

Từng bước mô tả này có thể giúp làm rõ những gì CPU đang làm. Trong bước đầu tiên, CPU lấy byte chỉ thị từ bộ nhớ. Để làm điều này, nó sao chép giá trị của thanh ghi ip đến bus địa chỉ và đọc byte tại địa chỉ đó. Điều này dùng một vòng đồng hồ.

Sau khi lấy được byte lệnh, CPU sẽ cập nhật ip cho nó tới byte tiếp theo của dòng lệnh. Nếu lệnh hiện tại là một lệnh nhiều byte, ip bây giờ sẽ chỉ vào toán hạng cho lệnh. Nếu lệnh hiện thời chỉ là lệnh một byte, ip sẽ được trỏ vào lệnh kế tiếp. Điều này dùng một vòng đồng hồ

Bước tiếp theo là để giải mã lệnh để xem nó làm gì. Điều này sẽ nói cho CPU biết, trong những thứ khác, nếu nó cần lấy thêm các byte toán hạng từ bộ nhớ. Điều này tốn một vòng đồng hồ.

Trong suốt quá trình giải mã, CPU xác định các loại toán hạng mà được lệnh yêu cầu. Nếu lệnh yêu cầu toán hạng 16 bit (ví dụ, nếu trường mmm là 101, 110, hoặc 111) thì CPU lấy hằng từ bộ nhớ. Bước này yêu cầu 0, 1, hoặc 2 vòng đồng hồ. Nó yêu cầu không vòng đồng hồ nếu có toán hạng không là 16 bit; nó yêu cầu một vòng đồng hồ nếu toán hạng 16 bit là word-aligned (đó là, bắt đầu tại một địa chỉ chẵn); nó yêu cầu hai vòng đồng hồ nếu toán hạng không phải là word aligned (đó là, bắt đầu tại một địa chỉ lẻ).

Nếu CPU lấy một toán hạng 16 bit, thì nó phải tăng ip lên hai lần để nó chỉ vào byte kế tiếp sau toán hạng. Phép toán này cần không hoặc một vòng đồng hồ. Không vòng đồng hồ nếu không có toán hạng; một nếu một toán hạng có mặt.

Tiếp theo, CPU tính toán địa chỉ của toán hạng nhớ. Bước này chỉ yêu cầu trường mmm của byte lệnh là 101 hoặc 100. Nếu trường mmm chứa 101, thì CPU tính toán tổng của thanh bx và hằng 16 bit; điều này yêu cầu hai vòng đồng hồ, một vòng để lấy giá trị của bx, vòng khác để tính tổng của bx và xxxx. Nếu trường mmm chứa 100, thì CPU sẽ lấy giá trị trong bx cho địa chỉ bộ nhớ, điều này yêu cầu một vòng. Nếu trường mmm không chứa 100 hoặc, thì bước này cần không vòng.

Việc lấy toán hạng ần 0, 1, 2, hoặc ba vòng phụ thuộc vào chính toán hạng đó. Nếu toán hạng là hằng số (mmm=111), thì bước này yêu cầu không vòng bởi vì chúng ta đã lấy hằng này từ bộ nhớ trong bước trước. Nếu toán hạng là thanh ghi (mmm = 000, 001, 010, or 011) thì bước này dùng một vòng đồng hồ. Nếu đây là toán hạng bộ nhớ word aligned (mmm=100, 101, hoặc 110) thì bước này dùng hai vòng đồng hồ. Nếu nó không là toán hạng bộ nhớ word aligned, thì nó cần ba vòng đồng hồ để lấy giá trị của nó. Bước cuối cùng cho lệnh mov là lưu giá trị vào trong địa chỉ đích . Vì đích của lệnh được nạp luôn luôn là một thanh ghi, nên phép toán dùng dùng một vòng đồng hồ.

Nói chung, chỉ thị mov cần giữa 5 và 11 vòng, phụ thuộc vào toán hạng của nó và địa chỉ bắt đầu trong bộ nhớ.

CPU làm các công việc cho chỉ thị mov memory, reg như sau:

-Lấy byte chỉ thị từ bộ nhớ (một vòng đồng hồ)
-Cập nhật ip để trỏ tới byte kế tiếp (một vòng đồng hồ)
-Giải mã lệnh để xem nó làm gì (một vòng đồng hồ)
-Nếu cần thiết, thì lấy một toán hạng từ bộ nhớ (không vòng nếu hình thức địa chỉ [bx], một vòng nếu hình thức địa chỉ [xxxx], [xxxx+bx], hoặc xxxx và giá trị trực tiếp xxxx sau mã máy bắt đầu từ địa chỉ chẵn, hoặc hai vòng đồng hồ nếu giá trị xxxx bắt đầu từ địa chỉ lẻ)
-Nếu cần thiết, cập nhật ip để trỏ toán hạng kế sau (không vòng nếu không có toán hạng nà, một vòng nếu toán hạng có mặt).
-Tính toán địa chỉ toán hạng (không vòng nếu hình thức địa chỉ không là [bx] hoặc [xxxx+bx], một vòng nếu hình thức địa chỉ là [bx], hoặc hai vòng nếu hình thức địa chỉ là [xxxx+bx]).
-Nhận giá trị của thanh ghi để chứa
-Cất giá trị được lấy vào trong địa chỉ nguồn (một vòng nếu một thanh ghi, hai vòng nếu toán hạng nhớ word-aligned, hoặc ba vòng đồng hồ nếu một toán hạng địa chỉ lẻ)

Thời gian cho các lệnh mov khác nhau là khác nhau bởi vì chỉ dẫn đó có thể đọc dữ liệu từ bộ nhớ; phiên bản này của lệnh mov nạp dữ liệu của nó từ một thanh ghi. Chỉ thị này dùng 5 tới 11 vòng đồng hồ để thực hiện.

Các chỉ thị add, sub, cmp, and, và or làm như sau:

- Lấy byte lệnh từ bộ nhớ (một vòng đồng hồ)
-Cập nhật thanh ghi ip để trỏ vào byte kế tiếp (một vòng đồng hồ)
-Giải mã lệnh (một vòng đồng hồ)
-Nếu cần thiết, lấy toán hạng hằng từ bộ nhớ (không vòng nếu hình thức địa chỉ [bx], một vòng nếu [xxxx], [xxxx+bx], hoặc hình thức địa chỉ xxxx và giá trị trực tiếp xxxx sau mã máy bắt đầu từ địa chỉ chẵn, hoặc 2 vòng đồng hồ nếu giá trị xxxx bắt đầu từ địa chỉ lẻ).
-Nếu cần thiết, cập nhật thanh ghi ip trỏ vào kế sau toán hạng hằng số (không hoặc một vòng đồng hồ).
-Tính địa chỉ của toán hạng (không vòng nếu hình thức địa chỉ không là [bx] hoặc [xxxx+bx], một vòng nếu hình thức địa chỉ là [bx], hoặc hai vòng nếu hình thức địa chỉ là [xxxx+bx]).
-Lấy giá trị của toán hạng và gửi nó tới ALU (không vòng nếu một hằng số, một vòng nếu một thanh ghi, hai vòng nếu toán hạng bộ nhớ word-aligned, hoặc ba vòng nếu địa chỉ toán hạng bộ nhớ lẻ).
-Lấy giá trị đầu tiên của toán hạng (một thanh ghi) và gửi nó tới ALU (một vòng đồng hồ).
-Chỉ thị ALU để cộng, trừ, so sánh, logic and, hoặc logic or cho giá trị (một vòng đồng hồ).
-Lưu kết quả trở lại vào toán hạng thanh ghi đầu tiên (một vòng đồng hồ).

Các lệnh này yêu cầu giữa tám và mười bảy vòng đồng hồ để thực hiện.

Chỉ thị not cũng tương tự như trên, nhưng có lẽ nó nhanh hơn vì chỉ có một toán hạng:

-Lấy byte lệnh từ bộ nhớ (một vòng đồng hồ).
-Cập nhật ip để trỏ tới byte tiếp theo (một vòng đồng hồ)
-Giải mã lệnh (một vòng đồng hồ).
-Nếu cần thiết, lấy toán hạng hằng từ bộ nhớ (không vòng nếu hình thức địa chỉ [bx], một vòng nếu hình thức địa chỉ [xxxx] hoặc [xxxx+bx] và giá trị trực tiếp xxxx sau đoạn mã máy bắt đầu trên địa chỉ chẵn, hoặc hai vòng đồng hồ nếu giá trị xxxx bắt đầu tại địa chỉ lẻ).
-Nếu cần thiết, cập nhật thanh ghi ip trỏ vào kế sau toán hạng hằng (một hoặc không vòng đồng hồ).
-Tính địa chỉ của toán hạng (không vòng nếu hình thức địa chỉ không là [bx] hoặc [xxxx+bx], một vòng nếu hình thức địa chỉ là [bx], hoặc hai vòng nếu hình thức địa chỉ là [xxxx+bx]).
-Lấy giá trị của toán hạng và gửi nó tới ALU (một vòng nếu một thanh ghi, hai vòng nếu toán hạng bộ nhớ word-aligned, hoặc ba vòng nếu địa chỉ toán hạng bộ nhớ lẻ).
-Chỉ thị cho ALU để thực hiện logic not giá trị (một vòng đồng hồ).
-Lưu kết quả trở lại vào toán hạng (một vòng nếu một thanh ghi, hai vòng đồng hồ nếu địa chỉ bộ nhớ chẵn, ba vòng nếu địa chỉ bộ nhớ lẻ).

Chỉ thị not dùng 6 tới 15 vòng để thực hiện.

Chỉ thị nhảy có điều kiện như làm việc như sau:

-Lấy byte lệnh từ bộ nhớ (một vòng đồng hồ)
-Cập nhật ip để trỏ tới byte tiếp theo (một vòng đồng hồ).
-Giải mã lệnh (một vòng đồng hồ).
-Lấy địa chỉ toán hạng đích từ bộ nhớ (một vòng nếu xxxx là địa chỉ chẵn, hai vòng đồng hồ nếu tại địa chỉ lẻ).
-Cập nhập ip để trỏ tới địa chỉ kế sau (một vòng đồng hồ)
-Kiểm tra các cờ CPU “bé hơn” và “bằng” (một vòng).
-Nếu giá trị cờ thích hợp với điều kiện nhảy đưa ra, thì CPU sẽ sao chép hằng 16 bit vào thanh ghi ip (không vòng nếu không phân nhánh, một vòng đồng hồ nếu phân nhánh xảy ra).

Lệnh nhảy không điều kiện là giống nhau trong việc thực hiện chỉ thị mov reg, xxxx ngoại trừ thanh ghi đích là thanh ghi ip x86 hơn là các thanh ghi ax, bx,cx, hay dx.

Các chỉ thị brk, iret, halt, put, và get chúng ta không quan tâm ở đây. Chúng xuất hiện trong tập chỉ thị chủ yếu cho các chương trình và các thí nghiệm. Chúng ta không thể đưa ra số lượng vòng cho chúng vì chúng có thể dùng một lượng thời gian không hạn định để hoàn thành nhiệm vụ của chúng.

To be continued...
[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|