Assembly - Chuỗi
Chúng tôi đã sử dụng các chuỗi có độ dài thay đổi trong các ví dụ trước của chúng tôi. Các chuỗi có độ dài thay đổi có thể có nhiều ký tự theo yêu cầu. Nói chung, chúng tôi chỉ định độ dài của chuỗi bằng một trong hai cách sau:
- Lưu trữ rõ ràng độ dài chuỗi
- Sử dụng một ký tự lính canh
Chúng ta có thể lưu trữ độ dài chuỗi một cách rõ ràng bằng cách sử dụng ký hiệu bộ đếm vị trí $ đại diện cho giá trị hiện tại của bộ đếm vị trí. Trong ví dụ sau:
msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string
$ trỏ đến byte sau ký tự cuối cùng của biến chuỗi msg . Vì thế,$-msgcho độ dài của chuỗi. Chúng tôi cũng có thể viết
msg db 'Hello, world!',0xa ;our dear string
len equ 13 ;length of our dear string
Ngoài ra, bạn có thể lưu trữ các chuỗi có ký tự sentinel ở cuối để phân tách một chuỗi thay vì lưu trữ độ dài chuỗi một cách rõ ràng. Ký tự sentinel phải là một ký tự đặc biệt không xuất hiện trong một chuỗi.
Ví dụ -
message DB 'I am loving it!', 0
Hướng dẫn chuỗi
Mỗi lệnh chuỗi có thể yêu cầu một toán hạng nguồn, một toán hạng đích hoặc cả hai. Đối với các phân đoạn 32 bit, các lệnh chuỗi sử dụng thanh ghi ESI và EDI để trỏ tới toán hạng nguồn và đích tương ứng.
Tuy nhiên, đối với các đoạn 16 bit, thanh ghi SI và DI được sử dụng để trỏ đến nguồn và đích tương ứng.
Có năm hướng dẫn cơ bản để xử lý chuỗi. Họ là -
MOVS - Lệnh này di chuyển 1 Byte, Word hoặc Doubleword của dữ liệu từ vị trí bộ nhớ sang vị trí khác.
LODS- Lệnh này tải từ bộ nhớ. Nếu toán hạng là một byte, nó được tải vào thanh ghi AL, nếu toán hạng là một từ, nó được tải vào thanh ghi AX và một từ kép được tải vào thanh ghi EAX.
STOS - Lệnh này lưu dữ liệu từ thanh ghi (AL, AX, hoặc EAX) vào bộ nhớ.
CMPS- Lệnh này so sánh hai mục dữ liệu trong bộ nhớ. Dữ liệu có thể có kích thước byte, từ hoặc từ kép.
SCAS - Lệnh này so sánh nội dung của một thanh ghi (AL, AX hoặc EAX) với nội dung của một mục trong bộ nhớ.
Mỗi lệnh trên đều có phiên bản byte, từ và từ kép, và các lệnh chuỗi có thể được lặp lại bằng cách sử dụng tiền tố lặp lại.
Các lệnh này sử dụng cặp thanh ghi ES: DI và DS: SI, trong đó thanh ghi DI và SI chứa các địa chỉ bù hợp lệ tham chiếu đến các byte được lưu trữ trong bộ nhớ. SI thường được kết hợp với DS (đoạn dữ liệu) và DI luôn được kết hợp với ES (đoạn phụ).
Thanh ghi DS: SI (hoặc ESI) và ES: DI (hoặc EDI) lần lượt trỏ đến toán hạng nguồn và toán hạng đích. Toán hạng nguồn được giả định là tại DS: SI (hoặc ESI) và toán hạng đích tại ES: DI (hoặc EDI) trong bộ nhớ.
Đối với địa chỉ 16 bit, thanh ghi SI và DI được sử dụng, và đối với địa chỉ 32 bit, thanh ghi ESI và EDI được sử dụng.
Bảng sau cung cấp các phiên bản khác nhau của lệnh chuỗi và không gian giả định của các toán hạng.
Hướng dẫn cơ bản | Toán hạng tại | Hoạt động Byte | Hoạt động từ | Hoạt động từ kép |
---|---|---|---|---|
MOVS | ES: DI, DS: SI | MOVSB | MOVSW | MOVSD |
LODS | AX, DS: SI | LODSB | LODSW | LODSD |
STOS | ES: DI, AX | STOSB | STOSW | STOSD |
CMPS | DS: SI, ES: DI | CMPSB | CMPSW | CMPSD |
SCAS | ES: DI, AX | SCASB | KHOÁ | SCASD |
Tiền tố lặp lại
Tiền tố REP, khi được đặt trước một lệnh chuỗi, ví dụ - REP MOVSB, gây ra sự lặp lại của lệnh dựa trên một bộ đếm được đặt tại thanh ghi CX. REP thực hiện lệnh, giảm CX đi 1 và kiểm tra xem CX có bằng không hay không. Nó lặp lại quá trình xử lý lệnh cho đến khi CX bằng không.
Cờ hướng (DF) xác định hướng của hoạt động.
- Sử dụng CLD (Clear Direction Flag, DF = 0) để thực hiện thao tác từ trái sang phải.
- Sử dụng STD (Đặt cờ hướng, DF = 1) để thực hiện thao tác từ phải sang trái.
Tiền tố REP cũng có các biến thể sau:
REP: Đó là sự lặp lại vô điều kiện. Nó lặp lại hoạt động cho đến khi CX bằng không.
REPE hoặc REPZ: Nó là lặp lại có điều kiện. Nó lặp lại thao tác trong khi cờ số không biểu thị bằng / không. Nó dừng khi ZF cho biết không bằng / không hoặc khi CX bằng không.
REPNE hoặc REPNZ: Nó cũng là lặp lại có điều kiện. Nó lặp lại hoạt động trong khi cờ số không cho biết không bằng / không. Nó dừng khi ZF cho biết bằng / không hoặc khi CX giảm xuống 0.