Bài thực hành số 3: Ngăn xếp – Thủ tục – Macro

Chia sẻ: Buihuu Tan | Ngày: | Loại File: DOC | Số trang:7

0
290
lượt xem
113
download

Bài thực hành số 3: Ngăn xếp – Thủ tục – Macro

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Ngăn xếp (Stack) là vùng nhớ đặc biệt được truy cập theo cơ chế “vào trước ra sau” (LIFO – Last In First Out), nghĩa là dữ liệu nào đưa vào sau sẽ được lấy ra trước. Ngăn xếp gồm nhiều phần tử, mỗi phần tử là một từ (2 bytes). Vị trí của ngăn xếp trong bộ nhớ được xác định bởi cặp thanh ghi SS:SP (SS chứa địa chỉ đoạn, SP chứa địa chỉ ô của đỉnh ngăn xếp). Khi chưa sử dụng, ngăn xếp rỗng, vị trí được xác định bởi SP lúc đó là đáy ngăn xếp....

Chủ đề:
Lưu

Nội dung Text: Bài thực hành số 3: Ngăn xếp – Thủ tục – Macro

  1. Bài thực hành số 3 Ngăn xếp – Thủ tục – Macro Mục đích  Hiểu được cơ chế hoạt động của ngăn xếp, quá trình gọi một thủ tục.  Biết cách sử dụng ngăn xếp, khai báo và gọi thủ tục.  Biết cách tạo và sử dụng macro. Tóm tắt lý thuyết Ngăn xếp 1. Một số lưu ý: − Ngăn xếp (Stack) là vùng nhớ đặc biệt được truy cập theo cơ chế “vào trước ra sau” (LIFO – Last In First Out), nghĩa là dữ liệu nào đưa vào sau sẽ được lấy ra trước. − Ngăn xếp gồm nhiều phần tử, mỗi phần tử là một từ (2 bytes). − Vị trí của ngăn xếp trong bộ nhớ được xác định bởi cặp thanh ghi SS:SP (SS chứa địa chỉ đoạn, SP chứa địa chỉ ô của đỉnh ngăn xếp). Khi chưa sử dụng, ngăn xếp rỗng, vị trí được xác định bởi SP lúc đó là đáy ngăn xếp. 2. Khai báo: .STACK Ví dụ: khai báo một vùng ngăn xếp có kích thước 256 bytes: .STACK 100h 3. Các thao tác: • Đưa trị vào (đỉnh) ngăn xếp: PUSH ; đưa nguồn (thanh ghi hay từ nhớ ; 16 bit) vào đỉnh ngăn xếp PUSHW ; đưa trực tiếp một hằng16 bit vào ; đỉnh ngăn xếp PUSHF ; đưa nội dung thanh ghi cờ vào đỉnh ; ngăn xếp • Lấy trị (ở đỉnh) ra khỏi ngăn xếp: POP ; lấy giá trị (2 bytes) ở đỉnh ngăn xếp ; đưa vào đích (thanh ghi (trừ thanh ; ghi IP) hay từ nhớ 16 bit) POPF ; lấy giá trị (2 bytes) ở đỉnh ngăn xếp ; đưa vào thanh ghi cờ Chú ý : Các lệnh PUSH, PUSHF, POP và POPF không ảnh hưởng tới các cờ. Ví dụ: Chương trình xuất chuỗi ngược dùng stack:
  2. .model small 1. Khai báo .stack 100h 000h … 0FCh .data 0FCh msg1 DB 'Nhap vao 1 chuoi: $' SS:SP  100h msg2 DB 10,13,'Chuoi nghich 2. Nhập lần lượt a,b,c đưa vào ngăn dao la: $' xếp: .code Nhập ký tự ‘a’: mov ax,@data 000h mov ds,ax … 0FCh mov ah,9 SS:SP  61 00 0FCh lea dx,msg1 Nhập ký tự ‘b’: 100h int 21h 000h mov cx,0 … 00 62 nhap: SS:SP  61 00 0FCh mov ah,1 Nhập ký tự ‘c’: 0FCh int 21h cmp al,13 100h je thongbaoxuat 00 63 xor ah,ah 00 62 000h push ax 00  61 SS:SP … inc cx 0FCh 3. Xuất các giá trị trong ngăn xếp jmp nhap Xuất ký tự ‘c’: 0FCh thongbaoxuat: 100h mov ah,9 00 63 lea dx,msg2 00 62 int 21h 00 61 000h xuat: Xuất ký tự ‘b’: SS:SP  … pop ax 0FCh mov dl,al 0FCh mov ah,2 00 62 100h int 21h 00 61 loop xuat Xuất ký tự ‘a’: 000h … mov ah,4ch SS:SP  0FCh int 21h 0FCh END 00 61 100h 000h … 0FCh SS:SP  0FCh 100h Thủ tục 1. Khai báo: PROC ;kiểu là NEAR(mặc định) hay FAR ; thân thủ tục ……………
  3. RET ENDP Thủ tục thường được viết ở cuối chương trình. 2. Gọi thủ tục: CALL CALL ; địa chỉ là thanh ghi hoặc vùng nhớ chứa địa chỉ ; thủ tục 3. Hoạt động của lời gọi thủ tục: Khi thực hiện lời gọi thủ tục (CALL) thì: − Địa chỉ ô của lệnh kế lệnh CALL (*) sẽ được cất vào ngăn xếp − Địa chỉ ô của lệnh đầu tiên trong thủ tục được đưa vào IP Khi thực hiện lệnh RET để quay về trình gọi thì: − Địa chỉ trong ngăn xếp được lấy ra và được vào IP. Do đó, nếu trong thủ tục có thao tác với ngăn xếp thì trong thủ tục, trước khi thao tác với ngăn xếp ta nên lưu lại địa chỉ (*) ở trên (chính là giá trị hiện thời trong ngăn xếp) để quay trở về trình gọi. Xem mô tả trong ví dụ sau. Ví dụ: Nhập xuất chuỗi kí tự
  4. .model small 1. Khai báo .stack 100h 000h .code … CALL Nhap 0FCh CALL Xuat 0FCh 2. Gọi ủ tục Nhap SS:SP th 100h mov ah,4ch int 21h 000h ;--------------------------------------------------- … Nhap PROC CALL Xuat 0FCh pop bx 0FCh SS:SP IP = địa chỉ ô lệnh “pop bx”  mov ah,2 3. Lưu lại địa chỉ quay về 100h mov dl,’?’ int 21h xor cx,cx 000h nhap: … mov ah,1 0FCh int 21h 0FCh BX = địa chỉ lệnh “CALL Xuat” cmp al,13 je ketthucnhap SS:SP ập ký tự a,b: 4. Nh  100h push ax inc cx 000h jmp nhap 00 62 00 61 … ketthucnhap: 0FCh push bx SS:SP  RET 5. Trả lại địa chỉ quay về 0FCh Nhap ENDP 100h BX = địa chỉ lệnh “CALL Xuat” ;--------------------------------------------------- Xuat PROC pop bx CALL Xuat mov ah,2 00 62 000h mov dl,13 SS:SP  61 00 … int 21h 0FCh mov dl,10 6. Kết thúc thủ tục Nhập: 0FCh int 21h 100h jcxz ketthucxuat xuat: 00 62 000h pop dx 00 61 … int 21h 0FCh SS:SP IP = địa chỉ ô lệnh “CALL Xuat”  loop xuat 0FCh ketthucxuat: Lời gọi thủ tục xuất (CALL Xuat) cũng 100h push bx hoạt động tương tự như trên. RET Xuat ENDP END
  5. Macro 1. Một số lưu ý: − Khi chúng ta có nhiều đoạn code giống nhau, chúng ta có thể sử dụng macro để thay thế, giống như chúng ta dùng define ở trong C. − Bản chất là thay thế lời gọi macro bằng các lệnh trong thân macro. − Các macro nên phục hồi những thanh ghi mà nó sử dụng trừ những thanh ghi chứa kết quả. 2. Khai báo: MACRO ; thân macro …………… ENDM 3. Hai cách sử dụng macro • Tạo macro trực tiếp trong chươnng trình: − Các macro thường được khai báo ở đầu chương trình trước phần .code. − Ví dụ: Xuất một chuỗi ra màn hình sử dụng macro .model small .stack 100h .data chuoi1 db “hello”,10,13,’$’ chuoi2 db “bye”,10,13,’$’ @xuatchuoi macro chuoi lea dx,chuoi mov ah,9 int 21h endm .code … @xuatchuoi chuoi1 @xuatchuoi chuoi2 … end • Xây dựng thư viện các macro: − Tạo 1 thư viện (tập tin) chứa các macro − include vào chương trình (thường trước phần .code) bằng lệnh include − Ví dụ: Xuất một chuỗi ra màn hình sử dụng thư viện macro THUVIEN.INC @xuatchuoi macro chuoi lea dx,chuoi mov ah,9 int 21h endm
  6. TestMacro.asm .model small .stack 100h .data chuoi1 db “hello”,10,13,’$’ chuoi2 db “bye”,10,13,’$’ INCLUDE THUVIEN.INC .code … @xuatchuoi chuoi1 @xuatchuoi chuoi2 … end 4. Các thành phần cục bộ của macro: − Trong macro, ta cũng có thể khai báo các biến, nhãn cục bộ để tránh gây ra lỗi khi gọi macro nhiều lần. − Cú pháp : LOCAL − Ví dụ: Xuất một chuỗi hằng ra màn hình sử dụng macro với biến cục bộ .model small .stack 100h @xuatchuoi macro chuoi LOCAL chuoicucbo, nhancucbo .data chuoicucbo db chuoi,’$’ .code lea dx,chuoicucbo mov ah,9 int 21h endm .code … nhancucbo: … @xuatchuoi @xuatchuoi ”bye” … end Lưu ý: nếu cần truyền chuỗi phức tạp thì ta cần sử dụng để báo cho trình biên dịch biết đây là một đối số.
  7. Tài liệu tham khảo 1. Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 6, ĐHKHTN, 2002 2. Randal Hyde, The art of assembly language programming – Chapter 11,12. 3. Norton Guide 4. Dan Rollins, TechHelp v.6.0 Bài tập Bài 1: Viết chương trình kiểm tra một biểu thức đại số có chứa các dấu ngoặc (như (), [] và {}) là hợp lệ hay không hợp lệ . Ví dụ: (a + [b – { c * ( d – e ) } ] + f) là hợp lệ nhưng (a + [b – { c * ( d – e )] } + f) là không hợp lệ. Bài 2: Tính giá trị biểu thức đã nhập ở bài tập 2 theo thứ tự từ trái sang phải. Bài 3: Viết lại các bài tập tuần trước dưới dạng các thủ tục Bài 4: Xây dựng một thư viện các macro Mở rộng 1. Có những cách nào để truyền tham số cho thủ tục ? để nhận kết quả trả về ? 2. Thử viết một thủ tục đệ quy. 3. Tìm hiểu cách phân chia chương trình thành nhiều file và cách biên dịch, liên kểt chúng. Hướng dẫn Bài 1. dùng ngăn xếp để PUSH các dấu ngoặc trái ( ‘(‘, ’{‘, ‘[‘ ) vào ngăn xếp. Nếu gặp dấu ngoặc phải ( ‘)’, ‘}’, ‘]’ ) thì POP từ stack ra. Nếu không POP được, hoặc POP ra không đúng loại với dấu ngoặc phải -> không hợp lệ . Ngược lại là biểu thức hợp lệ.
Đồng bộ tài khoản