4. Ngăn xếp và thủ tục
4.2 Chương trình con
Nhằm mục đích làm cho chương trình ngắn gọn và dễ hiểu, thông thường người ta thực hiện chia nhỏ chương trình thành các Module khác nhau, mỗi Module
có thể thực hiện một hoặc một khối công việc nhất định. Mỗi một Module đó được gọi là một chương trình con.
Trong lập trình hợp ngữ thông thường người ta chỉ sử dụng một loại chương trình con thủ tục. Cấu trúc của chương trình con loại này được thực hiện như sau:
a. Cấu trúc của chương trình con
<tên ctc> PROC [kiểu] ; thân chương trình con ;……… RET
<tên ctc> ENDP Trong đó:
+ tên ctc: là tên chương trình con mà người sử dụng tự đặt theo quy định đặt tên của ASSEMBLY.
+ PROC, ENDP: các lệnh giả được thực hiện để khai báo bắt đầu và kết thúc chương trình con.
+ kiểu: có thể là NEAR hoặc FAR.
NEAR (mặc định) có nghĩa là dòng lệnh gọi thủ tục ở cùng đoạn với thủ tục đó.
FAR có nghĩa là dòng lệnh gọi thủ tục ở trong một đoạn khác.
b. Ví dụ Xoa_mh PROC MOV AH,0 MOV AL,3 INT 10h RET Xoa_mh ENDP c. Một số chú ý:
Tránh trường hợp sau khi thực hiện xong chương trình con, nội dung các thanh ghi có thể bị thay đổi, thường người ta sử dụng lệnh PUSH và POP trong chương trình con để đưa tạm vào ngăn xếp và sau đó lấy lại thanh ghi. Ví dụ trong đoạn chương trình trên, sau khi thực hiện chương trình con xong, nội dung của thanh ghi AX có thể bị thay đổi. Ta có thể viết lại như sau:
Xoa_mh PROC
PUSH AX ;đẩy tạm AX vào ngăn xếp MOV AH,0
MOV AL,3
INT 10h
POP AX ;lấy lại giá trị cũ từ ngăn xếp cho AX
RET ; sau đó trở về chương trình chính
Xoa_mh ENDP
- Để người khác có thể đọc và hiểu rõ thủ tục thực hiện như thế nào thì, người lập trình phải có một đoạn giải thích như sau:
; Vào: (lấy thông tin từ chương trình gọi)
;Ra: (trả thông tin đã được xử lý về cho chương trình gọi) ; cách sử dụng (nếu có)
Ví dụ: Viết một thủ tục thực hiện nhân 2 số nguyên dương A và B bằng cách cộng và dịch các bit. Thuật toán: Tich = 0 Repeat If LSB(B) = 1 Then Tich = tich + A End_if SHL A,1 SHR B,1 Until B= 0 Đoạn mã: Nhan PROC
; nhan 2 so A,B bang phep dich cong cac bit ; Vao: AX = A; BX = B
; Ra: DX = ketqua
PUSH AX ;đẩy tạm vào AX vào ngăn xếp PUSH BX ;đẩy tạm vào BX vào ngăn xếp
XOR DX,DX ;xoá thanh ghi DX chứa tích
REPEAT: ;if B le
TEST BX,1 ; bit LSB của BX bằng 1? JZ END_IF ;khôngbằng 1, dịch trái AX… ;then
ADD DX,AX ;tich=tich+AX
END_IF:
SHL AX,1 ;dịch trái AX SHR BX,1 ;dịch phải BX ;until B=0
JNZ REPEAT ;B<>0, lặp lại POP BX ;khôi phục lại BX
POP AX ; và AX từ ngăn xếp
RET Nhan ENDP