Ngăn xếp, chương trình con, mảng dữ liệu

Một phần của tài liệu Kỹ thuật vi xử lý (Trang 101 - 123)

IV. GIỚI THIỆU CHƯƠNG TRÌNH EMU 8086

4.7. Ngăn xếp, chương trình con, mảng dữ liệu

Phần này giới thiệu các kiến thức cơ bản về cách sử dụng các kiểu cấu trúc dữ liệu ngăn xếp, mảng và cách thực hiện gọi chương trình con với ngôn ngữ assembly.

4.7.1. Giới thiệu về ngăn xếp (Stack)

Ngăn xếp là một đoạn bộ nhớ dùng để lưu trữ tạm thời giá trị của các thanh ghi. Trong ngôn ngữ lập trình assembly chúng ta chỉ có bốn thanh ghi đa năng đó là AX, BX, CX và DX. Trong khi lại có rất nhiều vấn đề cần đến các thanh ghi này. Vì thế chúng ta cần tái sử dụng thanh ghi này nhiều lần. Vấn đề được xử lý bằng cách lưu giữ giá trị hiện thời của AX vào đoạn ngăn xếp. Và khi đó ta có thể thực hiện các nhiệm vụ khác với AX. Công việc đầu tiên (lưu giá trị của AX vào ngăn xếp) được làm bởi lệnh PUSH. Việc thứ 2 (lấy lại giá trị của AX từ ngăn xếp) được làm bởi lệnh POP trong ngôn ngữ lập trình assembly.

Xem chương trình sau:

MOV AX, 3256H; Copy 3256H vào AX. Đây là giá trị gốc của AX.

94

PUSH AX; Đẩy giá trị của AX vào ngăn xếp

MOV AX, 1254H; Gán giá trị tức thời cho AX là 1254H

DEC AX; Giá trị mới của AX là 1253H. Ta thấy giá trị của AX đã bị thay đổi.

POP AX; Lấy lại giá trị cũ của AX và bây giờ AX là 3256H

Đoạn ngăn xếp là một đoạn khác với đoạn 0000 (ở đó chúng ta dùng để làm việc). Nó là một mảng ô nhớ dùng để chứa các giá trị.

Mỗi lần có một lệnh được gọi PUSH, giá trị của các thanh ghi tương ứng sẽ được lưu trữ vào ngăn bộ nhớ ngăn xếp. Nếu một lệnh PUSH khác được gọi thì giá trị của các thanh ghi tương ứng được lưu vào ô nhớ mà có địa chỉ thấp hơn 2 bytes so với ô nhớ trước.

Chúng ta có thể nhìn thấy sau đây:

Đây là một số dòng lệnh đơn giản.

Ở dòng 1 AX được đẩy vào.

Ta giả sử ngăn xếp được bắt đầu với địa chỉ có giá trị là 100H. Nó được gọi là Stack Pointer (SP trỏ đến vị trí mà dữ liệu được đẩy vào).

Hiện tại giá trị của AX được lưu trữ ở địa chỉ 100H. Con trỏ ngăn xếp (SP) được đổi thành 0FEH. Điều đó có nghĩa là nó bị giảm đi 2.

Nếu giá trị của BX được đẩy vào sau đó thì giá trị đó được lưu ở địa chỉ 0FEH và giá trị mới của SP là 0FCH.

Cuối cùng giá trị của CX được đẩy vào và nó được lưu tại địa chỉ 0FCH.

Ta có thể xem các hình sau để biểu diễn các lệnh số 1.; 2.; 3.; và 7.; 8.; 9.

được nêu ở trên như sau:

00F2H 00F4H 00F6H 00F8H 00FAH 00FCH 00FEH 0100H 1. PUSH AX

2. PUSH BX 3. PUSH CX 4. ...

5. ...

6. ...

7. POP CX 8. POP BX 9. POP AX

95

Bắt đầu:

(1) Sau khi gọi lệnh: PUSH AX 00F2H

00F4H 00F6H 00F8H 00FAH 00FCH 00FEH

0100H AX

(2) Sau khi gọi lệnh: PUSH BX 00F2H

00F4H 00F6H 00F8H 00FAH 00FCH 00FEH BX 0100H AX

(3) Sau khi gọi lệnh: PUSH CX 00F2H

00F4H 00F6H 00F8H 00FAH

00FCH CX 00FEH BX 0100H AX

Khi lệnh POP được thực thi thì giá trị cuối cùng chứa trong ngăn xếp sẽ được giải phóng trước tiên. Ở đây lệnh POP CX phải được gọi trước khi có thể lấy BX và

96

AX. Lệnh POP tự động tăng giá trị của SP lên 2. Vì thế hoạt động của lệnh POP là ngược lại với lệnh PUSH.

(7) Sau khi gọi lệnh: POP CX 00F2H

00F4H 00F6H 00F8H 00FAH 00FCH 00FEH BX 0100H AX

(8) Sau khi gọi lệnh: POP BX 00F2H

00F4H 00F6H 00F8H 00FAH 00FCH 00FEH

0100H AX

(9) Sau khi gọi lệnh: POP AX 00F2H

00F4H 00F6H 00F8H 00FAH 00FCH 00FEH 0100H

4.7.2. Lệnh CALL và RET

97

Giống như ‘C’ hay ‘MATLAB’, trong ngôn ngữ assembly, ta có thể tạo ra các hàm mà có thể truy cập từ chương trình chính. Lệnh CALL được dùng để truy cập một hàm. Mỗi hàm được kết thúc bởi một lệnh RET để trở lại chương trình chính.

4.7.3. Mảng dữ liệu

Mảng là một chuỗi dữ liệu được lưu trữ trong một vùng bộ nhớ. Nó được biểu diễn trong hình dưới đây:

Location Content

200H 1

202H 2

204H 3

206H 4

208H 5

20AH 6

20CH 7

Lệnh để chèn một mảng trong ngôn ngữ assembly là:

W DW 10,20,30,40,50,60 hoặc:

MSG DB ‘abcde’

Ở đây DW là dữ liệu dạng word (2 bytes) hay mảng word, DB là dữ liệu dạng byte hay mảng byte. W và MSG là tên mảng. [W] chỉ đến địa chỉ bắt đầu của mảng.

Lệnh DUP được dùng để tạo ra một mảng có các số giống nhau. Ví dụ:

ALPHA DW 100 DUP(0)

Tạo ra một mảng chứa 100 số 0. DUP cũng có thể được lồng vào nhau.

GAMMA DB 5, 4, 3 DUP (2, 3 DUP (0), 1): Tạo ra một mảng gồm 5,4,2,0,0,0,1,2,0,0,0,1,2,0,0,0,1

Truy nhập vào mảng trong bộ nhớ rất dễ dàng. Giả sử chúng ta có W là một mảng có 50 phần tử. Chúng ta cần đổi chỗ giá trị ở vị trí 25 với giá trị ở vị trí 31.

Hiện tại W chỉ vị trí đầu tiên của mảng. W+2 vị trí thứ hai, W+4 vị trí thứ 3. Vì thế W+48 chỉ vị trí 25 và W+60 là 31. Và mã lệnh sẽ như sau:

MOV AX, W+48

Starting address of the array

98

XCHG W+60, AX MOV W+48, AX

99

BÀI TẬP ÔN TẬP Bài tập trắc nghiệm

1. Đoạn chương trình sau đây làm công việc gì?

MOV AH,1 INT 21H MOV AH,2 MOV DL,AL INT 21H

a. Cho phép nhập 1 kí tự từ bàn phím.

b. Cho phép nhập 1 kí tự từ bàn phím và thoát về DOS.

c. Cho phép nhập 1 kí tự từ bàn phím và hiển thị kí tự đó ở đầu dòng tiếp theo.

d. Cho phép nhập 1 kí tự từ bàn phím và hiển thị kí tự đó 2. Cho biết đoạn chương trình sau làm nhiệm vụ gì?

MOV AX,0 MOV BX,0 MOV CX,255 TOP:

ADD BL,1 ADD AX,BX LOOP TOP

a. Thực hiện phép toán cộng AX= 0+1+2+…+254 b. Thực hiện phép toán cộng AX= 1+1+2+…+255 c. Thực hiện phép toán cộng AX= 1+2+3+…+256 d. Thực hiện phép toán cộng AX= 1+2+3+…+255 3. Tìm giá trị của AL sau đoạn chương trình sau:

MOV AL,75h AND AL,0Eh a. 05h b. 24h c. 4d

d. 00001010b

100

4. Chương trình nhập 10 số tự nhiên gồm 1 chữ số và cất vào ngăn xếp 10 số đó.

a. MOV CX,10 L:

MOV AH,1 INT 21h AND AL,0Fh PUSH AX LOOP L

b. MOV CX,10 L:

MOV AH,1 INT 21h AND AL,0Fh PUSH AL LOOP L

c. MOV CX,10 L:

MOV AH,1 INT 21h AND AL,0Fh POP AX LOOP L

d. MOV CX,10 L:

MOV AH,1 INT 21h AND AL,0Fh POP AL LOOP L

5. Cho biết kết quả của thanh ghi AH khi Vi xử lý thực hiện xong đoạn chương trình sau:

XOR AX,AX T:

INC AL ADD AH,AL CMP AL,9 JNE T

a. 45 b. 55 c. 2Eh d. 44

6. Cho biết đoạn chương trình sau làm nhiệm vụ gì?

MOV AL,1 MOV BL,1

101

MOV CX,5 TOP:

INC BL MUL BL LOOP TOP

a. Thực hiện phép tính AX=6!

b. Thực hiện phép tính AX=5!

c. Thực hiện phép tính AL=5!

d. Cả a,b,c đều sai

7. Câu lệnh thiết lập các bít LSB và MSB của AL trong khi giữ nguyên các bít khác?

a. XOR AL,81h b. OR AL,81h c. AND AL,81h d. TEST AL,81h

8. Đoạn chương trình sau đây làm công việc gì?

MOV AH,1 INT 21h MOV AH,2 MOV DL,10 INT 21h MOV DL,13 INT 21h MOV DL,BL INT 21h

a. Cho phép nhập 1 kí tự từ bàn phím và hiển thị kí tự đó

b. Cho phép nhập 1 kí tự từ bàn phím và hiển thị kí tự đó ở đầu dòng tiếp theo.

c. Cho phép nhập 1 kí tự từ bàn phím và hiển thị kí tự đó ở cạnh kí tự vừa nhập

d. Cả a, b, c đều sai

102

9. Kết quả của phép nhân giữa hai số 200 và 3 ở hệ thập phân được chứa trong thanh ghi nào?

a. AH b. AL c. AX

d. b và c đều đúng

10. Tìm giá trị của AH sau đọan chương trình sau:

MOV AH,75h OR AH,0Eh

a. 7Eh b. 7Fh c. 05d

d. 11111010b

11. Tìm kết quả của AX sau đoạn chương trình sau:

MOV AL,0 MOV BL,8 MUL BL MOV BH,8 MUL BH

a. 0 b. 64 c. 8

d. Cả a, b, c đều sai

12. Chương trình kiểm tra nội dung của AL. nếu bằng 0 thì không làm gì, nếu khác 0 thì xoá AL

a. AND AL,0FFh JNZ T

XOR AL,AL T:

b. CMP AL,0 JE T

AND AL,01h T:

c. CMP AL,0 JNE T

AND AL,00h T:

d. AND AL,0FFh JZ T

XOR AL,AL T:

103

13. Kết quả của phép nhân giữa hai số 2000 và 300 ở hệ thập phân được chứa trong (cặp) thanh ghi nào?

a. DX b. AX c. AX DX d. DX AX

14. Cho biết đoạn chương trình sau làm nhiệm vụ gì?

MOV AL,1 MOV BL,0 MOV CX,5 TOP:

INC BL MUL BL LOOP TOP

a. Thực hiện phép tính AL=6!

b. Thực hiện phép tính AX=5!

c. Thực hiện phép tính AL=5!

d. Thực hiện phép tính AL=4!

15. Tìm giá trị của AH sau đọan chương trình sau:

MOV AH,75h NOT AH

a. 57h b. 240d c. 8Ah

d. 01110101b

16. Lệnh nào sau đây xoá các bit lẻ (d15, d13, .. , d3, d1) của thanh ghi AX và giữ nguyên các bit khác

a. TEST AX, 0AAAAh b. AND AX, 0AAAAh c. AND AX, 5555h d. XOR AX, 0AAAAh

104

17. Kết quả của phép chia: 256/5 được chứa ở đâu?

a. AH b. AL c. DX

d. AH và AL

18. Cờ nào được thiét lập sau lệnh 2 sau:

MOV AL,01h RCR AL,1

a. ZF b. CF c. OF d. IF

19. Giả sử trong AX chứa số 261, khi đọc AH thì được giá trị là bao nhiêu?

a. 255 b. 1 c. 6 d. 5

20. Cho biết đoạn chương trình sau làm nhiệm vụ gì?

MOV AX,0200H MOV BX,0 TOP:

MOV DL,40H INT 21h INC BX CMP BX,9 JNE TOP

a. Hiển thị 9 chữ @ trên 1 dòng b. Hiển thị 9 chữ @ ở mỗi dòng c. Hiển thị 10 chữ @

d. Cả a, b, c đều sai

21. Cho biết kết quả của thanh ghi DH khi vi xử lý thực hiện xong đoạn chương trình sau:

105

MOV AX,8008h MOV DL,00h MOV DH,88h PUSH DX PUSH AX POP DX

a. 80h b. 08h c. 00h d. 88h

22. Câu lệnh xóa các bít LSB và MSB của AL trong khi giữ nguyên các bít khác?

a. XOR AL,81h b. TEST AL,81h c. AND AL,81h d. AND AL,7Eh

23. Tìm giá trị của AH sau đọan chương trình sau:

MOV AH,75h AND AH,0Fh a. 75h b. 05h c. 57h d. 50h

24. Thành phần nào bắt buộc phải có trong mỗi câu lệnh?

a. Tên b. Mã lệnh c. Toán hạng d. Chú thích

25. Cách đặt tên biến nào sau đây là không hợp lệ trong ngôn ngữ Assembly?

a. 1_variable b. fEt

c. _bien d. ASSEM

106

26. "Mã lệnh và dữ liệu gói gọn trong một đoạn" là cách mô tả cho kiểu bộ nhớ nào sau đây?

a. Small b. Tiny c. Medium d. Compact

27. Cấu trúc FOR – DO được gọi là cấu trúc gì?

a. Tuần tự b. Rẽ nhánh c. Song song d. Lặp

28. BX phải được dịch mấy lần để dành chỗ cho 1 giá trị hex a. 2

b. 4 c. 8 d. 16

29. Hàm nào của ngắt 21h có tác dụng vào một phím?

a. 1 b. 2 c. 4 d. 9

30. Hàm nào của ngắt 21h có tác dụng hiển thị kí tự ra màn hình?

a. 1 b. 2 c. 4 d. 9

107

Bài tập tự luận

1. Nhập vào một dãy số 8 bit ở dạng thập phân, các số cách nhau bằng một dấu cách và kết thúc bằng phím ENTER. Sắp xếp dãy số theo thứ tự tăng dần và in ra màn hình.

2. Hãy viết chương trình hợp ngữ cho vi xử lý 8086 thực hiện Nhập số N (N<9, nguyên dương) từ bàn phím

Tính S = 12 + 22 +…..+ N2 Kiểm tra tính chẵn lẻ của S

3. Xây dựng một số chương trình con cơ bản để với mỗi chương trình đều có thể lắp ráp từ nhiều module nhỏ thành 1 chương trình lớn (cơ chế Bottom Up).

3.1 Tính tổng liên tiếp từ M đến N 3.2 Tính tích liên tiếp từ M đến N

3.3 Nhạp N số tự nhiên có 1 chữ số và lưu vào ngăn xếp

3.4 Nhập vào 1 số kiểm tra số đó có thuộc khoảng [M, N] hay không?

3.5 Kiểm tra số chẵn lẻ

3.6 Kiểm tra có phải số tự nhiên từ 0 đến 9 hay không?

3.7 In số có 4 chữ số vừa tính được ra màn hình Bài tập thực hành trên máy

(Cần ghi lời giải thích cho từng câu lệnh)

1. Viết các lệnh dưới đây và cho biết tác dụng. Xem hướng dẫn ở trên về cách tải và chạy chương trình.

a. MOV AX, 3012

Kiểm tra nội dung thanh ghi AX.

MOV BX, AX

Kiểm tra nội dung thanh ghi BX.

Điều gì đã xảy ra ở đây?

b. MOV AX,30h MOV [2010], AX MOV BX, [2010]

Kiểm tra nội dung thanh ghi BX.

Điều gì đã xảy ra ở đây?

108

c. MOV SI, 1256h MOV [SI], 3251h MOV AX, [SI]

Kiểm tra nội dung thanh ghi BX.

Điều gì đã xảy ra ở đây?

d. MOV AL, 87h NEG AL

NEG AL

Cho biết nội dung của AL trong từng lệnh.

2. Viết các lệnh dưới đây và cho biết tác dụng:

a. MOV AX, 1782H MOV BX, 1287H ADD AX, BX

Cho biết nội dung của các thanh ghi?

b. MOV AX, 1782H MOV BX, 1278H SUB AX, BX

Cho biết nội dung của các thanh ghi?

c.MOV AX,2782H MOV BX,1278H MUL BX

Cho biết nội dung của các thanh ghi?

d. MOV AX,57F2H MOV BX,1375H DIV BX

Cho biết nội dung của các thanh ghi?

3. Viết đoạn mã sau và chỉ ra tác dụng:

Chương trình 1:

MOV BX, 3256H MOV CX, 1554H

109

AND CX, BX HLT

Kiểm tra nội dung của CX. Điều gì đã xảy ra ở đây?

Chương trình 2:

MOV BX, 3256H MOV CX, 1554H XOR CX, BX HLT

Kiểm tra nội dung của CX. Điều gì đã xảy ra ở đây?

Chương trình 3:

MOV AX, 1027H MOV BX, 5A27H MOV CX, 54A5H OR AX, BX XOR AX, CX NOT AX TEST CX, BX AND CX, AX HLT

Chạy chương trình trên cở chế độ “single step” và ghi lại các giá trị của tất cả các thanh ghi cho mỗi lệnh. Chuyển các số ở dạng hexa ở trên thành dạng nhị phân cho tất cả các lệnh.

4. Viết đoạn mã sau và cho biết tác dụng của nó.

Chương trình 1:

MOV AX, 7A24H MOV BX, 15A3H SUB AX, BX JMP L3T2

EEE316: DIV BX JMP Last

110

L3T2: MOV CX, 45B1H AND AX, CX

TEST AX, BX JMP EEE316 Last: HLT

Chạy chương trình trên ở chế độ “single step” và ghi lại các giá trị của tất cả các thanh ghi cho mỗi lệnh. Giải thích tại sao lại dùng nhãn “Last” ở đoạn cuối? Điều gì sẽ xảy ra nếu không dùng nó?

Chương trình 2:

MOV AX, 7A24H MOV BX, 95A3H ADD AX, BX JC L3T2

EEE316: OR AX, 23H JNZ Last

L3T2: MOV CX, 0FC7H SUB AX, CX

JZ EEE316 Last: HLT

Cập nhật các giá trị của các thanh ghi trong từng lệnh.

5. Thực hiện các chương trình sau:

Chương trình 1 MOV CL, 02H MOV AX, 105AH SHL AX,CL HLT

Tính giá trị của thanh ghi AX từ giá trị trước và biểu diễn ở dạng nhị phân.

Đây là lệnh gì?

Chương trình 2 MOV CL, 04H

111

MOV AX, 564AH SAL AX, CL HLT

Tính giá trị của thanh ghi AX từ giá trị trước và biểu diễn ở dạng nhị phân.

Đây là lệnh gì?

6. Thực hiện các chương trình sau:

Chương trình 1:

MOV AX, 1025H MOV BX, 475AH MOV CX, 50H Lev: INC AX DEC BX LOOP Lev HLT

Xem xét cơ chế hoạt động của đoạn mã. Điều gì xảy ra trong vòng lặp?

Chương trình 2:

Tìm mẫu số chung lớn nhất của hai số:

MOV AX, 5H MOV BX, 3H Lev: XOR DX, DX DIV BX

MOV AX, BX MOV BX, DX TEST DX, 0FFH JNZ Lev

Đoạn mã trên dùng để tìm mẫu số chung lớn nhất của 5 và 3. Ta có thể thay đổi giá trị của AX và BX tính ra kết quả với các giá trị bất kỳ. Tìm mẫu số chung lớn nhất của 08D4H và 235H.

7. Thực hiện các chương trình sau:

Chương trình 1:

112

Chương trình này lưu hai giá trị vào AX và BX. Tìm phần dư của phép chia giữa AX và BX, và lưu nó vào BX. Giá trị của AX không được thay đổi.

Xem xét tất cả các lệnh và viết ý nghĩa của từng lệnh.

MOV AX, 3256H MOV BX, 125AH PUSH AX

LEV: SUB AX,BX CMP AX, BX JG LEV

MOV BX, AX POP AX

Chương trình 2:

Ở đây việc BX được cộng vào AX được lặp CX lần. Xác định giá trị của AX, BX, CX sau khi kết thúc vòng lặp. Xem xét tất cả các lệnh và viết ý nghĩa của từng lệnh.

CODE SEGMENT

ASSUME CS:CODE, DS:CODE MOV AX, 42A6H

MOV BX, 2E5AH MOV CX, 12H PUSH AX PUSH BX PUSH CX

LEV: ADD AX, BX LOOP LEV

POP CX POP BX POP AX

8. Thực hiện các chương trình sau:

Chương trình 1:

113

Thực hiện phép nhân, ở đây phép nhân sẽ được thực hiện bởi phép dịch và cộng như sau:

1101 x 1011 = ? MAIN PROC MOV AX, 123H MOV BX, 16H CALL MULTIPLY MULTIPLY PROC PUSH AX

PUSH BX XOR DX, DX REPEAT:

TEST BX, 1 JZ END_IF ADD DX, AX END_IF;

SHL AX, 1 SHR BX, 1 JNZ REPEAT POP BX POP AX RET

MULTIPLY ENDP END MAIN

Chương trình 2:

Tính mẫu số chung lớn nhất (GCD) của từ ba số trở lên. Nó sử dụng một thủ tục để tính GCD của hai số, được thảo luận ở bài thí nghiệm trước.

MAIN PROC MOV AX, 9H MOV BX, 5H

114

MOV CX, 4H MOV DX, 3H CALL GCD MOV BX, CX XCHG AX, BX CALL GCD MOV BX, DX XCHG AX, BX CALL GCD HLT

GCD PROC PUSH CX PUSH DX MOV DX, 0H LEV: SUB AX, BX CMP AX, BX JG LEV

MOV CX, AX MOV AX, B X MOV BX, CX CMP BX, DX JNE LEV POP CX POP DX RET

GCD ENDP END MAIN

CHƯƠNG 4.TỔ CHỨC VÀO RA DỮ LIỆU CHO VI XỬ LÝ 8088/8086

Chương 4 giúp cho người đọc nắm được nguyên tắc ghép nối giữa vi xử lý 8088/8086 của hãng Intel với bộ nhớ và thiết bị ngoại vi. Các chân tín hiệu của vi xử lý, phương pháp giải mã địa chỉ, cách ghép nối và các ví dụ minh họa sẽ được trình bày chi tiết trong chương này.

MỤC TIÊU CHƯƠNG NỘI DUNG CHƯƠNG

Mang lại các kiến thức để người đọc hiểu được cấu trúc sơ đồ chân tín hiệu của vi xử lý 8088 và các mạch điều khiển ghép nối phụ trợ.

Giúp cho người đọc hiểu cấu trúc và phân biệt các loại bộ nhớ bán dẫn. Hiểu các phương pháp ghép nối giải mã địa chỉ bộ nhớ cho vi xử lý 8088/8086.

Hỗ trợ người đọc hiểu và biết phương pháp ghép nối giải mã địa chỉ cổng vào ra cho vi xử lý 8088/8086, cách ghép nối trao đổi dữ liệu giữa vi xử lý 8088 với vi mạch song song lập trình được 8255A.

Một phần của tài liệu Kỹ thuật vi xử lý (Trang 101 - 123)

Tải bản đầy đủ (PDF)

(251 trang)