Viết thủ tục định thời
Mục đích-yêu cầu:
- Giúp cho sinh viên hiểu về thủ tục định thời.
- Tìm hiểu kỹ về các lệnh POP, PUSH, POPF, PUSHF, RET.
- Làm quen với các lệnh gọi CALL, ngăn xếp và địa chỉ bắt đầu của thủ tục làm trễ.
Kiến thức nền:
1/ Lệnh MOV AL,8:
Con số 8 là giá trị được cất trong thanh ghi AL trước khi gọi thủ tục delay. Giá trị này xác định thời gian trễ của việc trì hoãn.
2/ Lệnh CALL 30:
Trong lập trình thường gặp những đoạn lệnh được dùng đi dùng lại nhiều lần trong chương trình. Lúc này người lập trình chỉ viết một lần đoạn chương trình đó rồi dùng lệnh CALL để chuyển việc thực hiện chương trình tới chương trình cần lập đi lập lại này. Lệnh CALL 30 gọi thủ tục tại địa chỉ [30] và thay đổi con trỏ lệnh IP đến địa chỉ [30] và chương trình tiếp tục thi hành từ địa chỉ đó. Ðịa chỉ quay về này được lưu trong ngăn xếp. Bạn hãy nhấp vào đây để xem minh họa cách gọi chương trình con. Trong đoạn phimbạn vừa xem mỗi khi lệnh được thực hiện nó sẽ nhấp nháy. Như vậy, nhờ vào sử dụng chương trình con, chương trình chính đơn giản đi rất nhiều.
Khi một chương trình con được gọi đến, địa chỉ trở về được tự động cất vào ngăn xếp. Cuối chương trình con, khi gặp lệnh RET địa chỉ trở về được tự động lấy ra từ ngăn xếp. Chính nhờ cấu trúc này, chương trình cho phép sử dụng nhiều mức chương trình : chương trình con này gọi được chương trình con khác. Ðể hiểu rõ hơn bạn hãy nhấp vào.
3/ Ngăn xếp (stack):
Ðây là một vùng bộ nhớ mà ở đó giá trị được lưu và cất giữ lại. Ngăn xếp sử dụng quy tắc vào sau ra trước (LIFO). Ðể dễ hiểu hơn, có thể xem ngăn xếp như một chồng tài liệu đặt trong hộc tủ. Khi các tập (tệp) tài liệu được xếp lần lượt vào hộc thì tập tài liệu được cất vào cuối cùng có thể lấy ra trước tiên : nghĩa là vào sau ra trước. Với cấu trúc LIFO, vị trí chính xác nơi cất giữ dữ liệu không quan trọng bằng trật tự mà dữ liệu được cất. Lệnh Call lưu địa chỉ quay về vào ngăn xếp. Lệnh Ret lấy lại giá trị lưu từ ngăn xếp và nhảy đến địa chỉ bằng việc thiết lập con trỏ lệnh IP.
Con trỏ ngăn xếp SP (Stack Pointer) được dùng để trỏ vào ô vừa được dùng đến của ngăn xếp. Chương trình mặc định trong phần mềm dành các ô nhớ từ ô BF trở đi làm ngăn xếp. Nội dung của con trỏ ngăn xếp sẽ tự động giảm mỗi khi có một byte mới được cất vào ngăn xếp.
4/ Lệnh ORG 30:
Là lệnh bắt đầu từ địa chỉ 30. ORG xác định lại những gì mà mã máy phát ra. Thủ tục định thời được cất tại địa chỉ 30.
5/ Lệnh PUSH AL:
Ðược dùng để lưu giá trị của AL vào ngăn xếp con trỏ ngăn xếp SP chỉ tới vị trí ngăn xếp trống kế tiếp và lệnh PUSH cất giá trị tại vị trí này. Sau đó SP được di chuyển đến ô nhớ kế tiếp. Trong chương trình mô phỏng, ngăn xếp tăng lên hướng về địa chỉ zero. Ngăn xếp sẽ bị tràn nếu chứa nhiều hơn so với bộ nhớ sẵn có.
6/ Lệnh PUSHF:
Dùng để cất các cờ của CPU trong thanh ghi trạng thái SR vào ngăn xếp. Ðiều này bảo đảm rằng các cờ có thể đặt lại như cũ khi thủ tục hoàn thành. Con trỏ ngăn xếp được lùi lại một khoảng trống.
7/ Lệnh DEC AL:
Giảm giá trị trong AL đi một đơn vị. Lệnh này thiết lập cờ Z nếu kết quả là 0 hay cờ S nếu kết quả có giá trị (-) .
8/ Lệnh JNZ REP:
JNZ nhảy tới địa chỉ mà Rep đánh dấu. Nhảy nếu cờ Z không được set.
9/ Lệnh POPF:
Dùng để khôi phục các cờ CPU từ ngăn xếp. Tăng con trỏ ngăn xếp lên 1.
10/ Lệnh POP AL:
Dùng khôi phục thanh ghi AL từ ngăn xếp. Ðiều này được làm bởi việc di chuyển con trỏ ngăn xếp ban đầu tới một nơi phía trước và chép giá trị tại vị trí ngăn xếp vào thanh ghi AL.
11/ Lệnh RET:
RET được đặt tại cuối chương trình con để CPU lấy lại địa chỉ trở về ( địa chỉ tiếp theo lệnh CALL trong chương trình chính), địa chỉ này được tự động cất khi gọi chương trình con. Thủ tục định thời có thể được tái sử dụng nhiều lần, gọi là sử dụng lặp lại (recursion). Ðây là một kỹ thuật mạnh nhưng dễ làm rối loạn chương trình, nếu bạn không hiểu những gì đang xảy ra. Sự lặp ngẫu nhiên hay không điều khiển được làm cho ngăn xếp tăng lên cho đến khi nó ghi đè lên ngăn xếp hay bị tràn.
Chương trình:
;Chương trình chính ----------------------------------------------------------------
Start:
MOV AL,8 ;một trì hoãn ngắn
CALL 30 ;gọi thủ tục tại địa chỉ 30
MOV AL,10 ;một trì hoãn trung bình
CALL 30
MOV AL,20 ;một trì hoãn dài
CALL 30
JMP Start ;nhảy về Start
;Thủ tục delay được lưu ở địa chỉ 30 ---------------------------------------------
ORG 30 ;khởi đầu thủ tục từ địa chỉ [30]
PUSH AL ;lưu AL từ ngăn xếp
PUSHF ;lưu các cờ CPU vào ngăn xếp
Rep:
DEC AL ;giảm AL đi 1
JNZ Rep ;nhảy đến nhãn Rep nếu AL khác ;0
POPF ;khôi phục các cờ CPU từ ngăn ;xếp
POP AL ;khôi phục AL từ ngăn xếp
RET ;trở về lại chương trình chính (từ chương trình con)
END
;--------------------------------------------------------------------------------------
Tải file phim về ở đây