Tải bản đầy đủ (.pdf) (9 trang)

Kiến trúc máy tính - Bài thực hành số 1 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (252.35 KB, 9 trang )

1





THỰC HÀNH LẬP TRÌNH HỢP NGỮ
HƯỚNG DẪN SỬ DỤNG CÔNG CỤ DEBUG


2

Bài 1: Giới thiệu công cụ debug
Debug là công cụ gỡ rối, cho phép nạp một file chương trình và thực thi từng bước, xem và sửa
nội dung vùng nhớ, thanh ghi, sector đĩa, nhập một đoạn chương trình bằng mã gợi nhớ hay mã
máy vào một vị trí trong bộ nhớ
1.1. Khởi động và thoát công cụ debug
Công cụ Debug.EXE có sẵn trong các hệ điều hành của Microsoft như MS-DOS, Windows 9x,
2000, XP, Vista. Tùy thuộc vào hệ điều hành nào mà file Debug.EXE nằm ở các vị trí đường dẫn
khác nhau. Trên hệ điều hành Windows có thể khởi động công cụ này bằng cách gõ vào
Debug.EXE vào hộp TextBox Run (hoặc “Start Search” với Windows Vista).

Khởi động Debug từ Windows XP và Vista

Sau khi khởi động Debug, cửa sổ giao diện có dạng sau:

1.2. Cấu trúc và các dạng tham số của các lệnh debug
Debug là công cụ sử dụng chế độ dòng lệnh, người sử dụng gõ lệnh từ dấu nhắc con trỏ và xem
kết quả sau khi thực thi lệnh ngay trên màn hình. Danh sách các lệnh mà công cụ hỗ trợ:
Lệnh Ý nghĩa
A



[address] assembe - nhập đoạn chương trình bằng mã
lệnh gợi nhớ
3

C

range address compare - so sánh vùng nhớ
D

[range] dump - in nội dung vùng nhớ ra màn hình
E

address [list] enter - nhập nội dung một vùng nhớ
F

range list fill - điền nội dung vùng nhớ
G

[=address] [addresses] go - thực thi đoạn chương trình
H

value1 value2 hex - tính tổng và tích hai số hệ 16
I

port input - nhập một giá trị từ cổng
L

[address] [drive]
[firstsector] [number]

load – nạp nội dung file hoặc sector
M

range address move – sao chép vùng nhớ
N

[pathname] name – đặt tên cho file sắp đọc/ghi
O

port byte output – xuất dữ liệu ra cổng
P

[=address] [number] proceed – thực thi một lệnh
Q

quit – thoát chương trình debug
R

[register] register – thao tác trên thanh ghi
S

range list search – tìm kiếm trên bộ nhớ
T

[=address] [number] trace – thực thi một lệnh
U

[range] unassemble – xem nội dung vùng nhớ ở
dạng lệnh gợi nhớ
W


[address] [drive]
[firstsector] [number]
write – ghi nội dung vùng nhớ lên file
hoặc sector

Lưu ý: Tham số ở trong cặp dấu [ ] là tùy chọn có hoặc không, tham số không có dấu [ ] bắt buộc
phải có.
1.3. Các thao tác cơ bản với công cụ debug:
1.3.1. Xem và sửa nội dung các thanh ghi (lệnh R)
Cú pháp: R [register]
Ý nghĩa: Với tham số register là tên của thanh ghi (AX, BX, CX, DX, CS, DS, …), thì lệnh này
hiển thị giá trị 16 bit của thanh ghi này ra màn hình và hiện dấu nhắc để nhập giá trị mới cho
thanh ghi này vào. Nếu không muốn thay đổi thì có thể gõ Enter để giữ nguyên giá trị cũ.
Nếu không có tham số register thì nội dung của tất cả các thanh ghi sẽ được hiển thị
Ví dụ:
Hiển thị nội dung thanh ghi AX và sửa thành giá trị 00FF :
-R AX
AX 1065
:00FF
Kiểm tra lại nội dung của AX:
-R AX
AX 00FF
:
-
Xem nội dung tất cả các thanh ghi:
4


Các thanh ghi đa dụng: AX,BX,CX,DX

Các thanh ghi đoạn: CS, DS, ES, SS
Các thanh ghi con trỏ và chỉ số: SI, DI, SP, BP
Thanh ghi con trỏ chương trình: IP
Thanh ghi trạng thái hiển thị dưới dạng các cờ sau:
Bit
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF




SET (a 1-bit) CLEARed (a 0-bit)
OV NV [No Overflow]
DN (decrement) UP (increment)
EI (enabled) DI (disabled)
NG (negative) PL (positive)
ZR [zero] NZ [ Not zero]
AC NA [ No AC ]
PE (even) PO (odd)
CY [Carry] NC [ No Carry]
Ví dụ thay đổi giá trị cờ DF thành DN và giá trị cờ SF thành NG:
-r F
NV UP EI PL NZ NA PO NC -DN NG
Xem lại đã thay đổi chưa:
-r F
NV DN EI NG NZ NA PO NC -
1.3.2. Xem nội dung vùng nhớ (lệnh D)
Cú pháp: D [range]
Ý nghĩa: Hiển thị nội dung vùng nhớ xác định bởi range
Ví dụ:

Hiển thị vùng nhớ từ C010:0000 đến C010:0050
-d c010:0000 0050
C010:0000 14 07 00 02 0C 64 1B 14-07 00 04 30 64 1C 14 07 d 0d
C010:0010 00 00 03 64 1C 14 07 00-02 0C 64 1C 14 07 00 04 d d
C010:0020 30 24 1C 14 07 00 06 C0-24 1D 14 07 00 00 03 64 0$ $ d
C010:0030 1D 14 07 00 02 0C D6 09-80 90 20 E0 1D 10 08 60 `
C010:0040 22 00 00 00 00 08 08 18-4E 0C 80 C8 20 E0 14 10 " N
C010:0050 10 .
CF PF
AF ZF
SF
IF DF

OF

5

Hiển thị vùng nhớ 24 (18h) byte bắt đầu từ C000:0010
-d C000:0010 L 18
C000:0010 30 30 1C 22 E9 35 21 9D-40 00 E0 0A 30 30 49 42 00.".5!.@ 00IB
C000:0020 4D 20 56 47 41 20 43 6F M VGA Co
Hiển thị vùng nhớ từ DS:0150 đến DS:0180
-r
AX=01FF BX=1008 CX=0507 DX=0516 SP=FFEE BP=0000 SI=0000 DI=0000
DS=17E1 ES=17E1 SS=17E1 CS=17E1 IP=0105 NV DN EI NG NZ NA PO NC
17E1:0105 0000 ADD [BX+SI],AL DS:1008=00
-d 150 180
17E1:0150 48 65 6C 6C 6F 20 41 73-73 65 6D 62 6C 79 21 00 Hello Assembly!.
17E1:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00

17E1:0180 00 .
Hiển thị vùng nhớ 128 byte ở địa chỉ DS:0150
-d 150
17E1:0150 48 65 6C 6C 6F 20 41 73-73 65 6D 62 6C 79 21 00 Hello Assembly!.
17E1:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:0180 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:0190 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:01A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
17E1:01C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
Lệnh d không có tham số: hiển thị 128 byte kế tiếp lần hiển thị trước

-d C700:0000 18
C700:0000 33 C9 B6 A0 E8 59 F7 B8-02 01 9D 75 02 33 C0 89 3 Y u.3
C700:0010 46 16 C7 46 12 00 02 B4-00 F F
-d
C700:0010 66 5A 5B C3 53 51 66 fZ[.SQf
C700:0020 52 B7 A0 B9 80 00 66 81-E2 FF FF 00 00 E8 6D 00 R f m.
C700:0030 72 02 EB 04 B4 00 EB 02-B4 01 66 5A 59 5B C3 01 r fZY[
C700:0040 10 04 40 08 80 02 20 50-51 52 56 83 F9 00 74 0B @ PQRV t.
C700:0050 B2 08 83 F9 02 74 1B 8A-D5 EB 17 E8 3C B8 8A E5 t <
C700:0060 B9 08 00 BE 3F 70 2E AC-84 E0 E1 FA B2 01 E3 02 ?p
C700:0070 8A D0 E8 05 00 5E 5A 59-58 C3 52 56 2E F6 06 1A ^ZYX.RV
C700:0080 0C 01 74 0C 80 FA 01 75-07 2E 8A 1E 41 0C EB 09 t u A
C700:0090 E8 CA EA 72 05 2E 8A 5C-13 r \.
Bài tập: Hiển thị ngày tháng của BIOS trên màn hình của debug biết thông tin này chứa trong 8
byte vùng nhớ bắt đầu ở địa chỉ FFFF:0005
1.3.3. Tìm kiếm nội dung vùng nhớ (lệnh S)
Cú pháp: S range list

Ý nghĩa: Tìm kiếm trong một vùng nhớ range một chuỗi các byte cung cấp trong tham số list.
Tham số list có thể là một danh sách các giá trị byte hoặc là 1 chuỗi ký tự bao đóng trong 2 dấu
nháy đơn hoặc kép.
Ví dụ:
Tìm chuỗi có giá trị “COM1” trong vùng nhớ từ 0000:0000 đến 0000:ffff :
6

-s 0000:0000 ffff "COM1"
0000:0776
0000:0C79
Tìm được 2 vị trí xuất hiện.
Dùng lệnh D để kiểm tra lại ở địa chỉ 0000:0776 :
-d 0:0776
0000:0770 43 4F-4D 31 20 20 20 20 90 00 COM1
0000:0780 70 00 C0 A8 EC 01 03 02-4C 50 54 31 20 20 20 20 p LPT1
0000:0790 A2 00 70 00 C0 A8 EC 01-0A 02 4C 50 54 32 20 20 p LPT2
0000:07A0 20 20 B4 00 70 00 C0 A8-EC 01 11 02 4C 50 54 33 p LPT3
0000:07B0 20 20 20 20 C6 00 70 00-00 80 EC 01 1E 02 43 4F p CO
0000:07C0 4D 32 20 20 20 20 D8 00-70 00 00 80 EC 01 24 02 M2 p $.
0000:07D0 43 4F 4D 33 20 20 20 20-FF FF 70 00 00 80 EC 01 COM3 p
0000:07E0 2A 02 43 4F 4D 34 20 20-20 20 10 14 00 00 C0 15 *.COM4
0000:07F0 59 F8 00 F0 19 F2 Y
Cũng có thể tìm theo chuỗi các giá trị byte như sau:
-s 0000:0000 0dff 43 4f 4d
0000:0774
0000:07C2
0000:07D4
0000:07E6

-d 0000:770

0000:0770 7A 02 A6 02 43 4F 4D 31-20 20 20 20 8E 00 70 00 z COM1 p.
0000:0780 C0 A0 7A 02 91 02 4C 50-54 31 20 20 20 20 A0 00 z LPT1
0000:0790 70 00 C0 A0 7A 02 98 02-4C 50 54 32 20 20 20 20 p z LPT2
0000:07A0 2D 01 70 00 C0 A0 7A 02-9F 02 4C 50 54 33 20 20 p z LPT3
0000:07B0 20 20 11 EA 27 27 3F FD-CA 00 70 00 00 80 7A 02 ''? p z.
0000:07C0 AC 02 43 4F 4D 32 20 20-20 20 DC 00 70 00 00 80 COM2 p
0000:07D0 7A 02 B2 02 43 4F 4D 33-20 20 20 20 00 00 6B 03 z COM3 k.
0000:07E0 00 80 7A 02 B8 02 43 4F-4D 34 20 20 20 20 E8 D2 z COM4

1.3.4. Sửa nội dung vùng nhớ (lệnh E)
Cú pháp: E address [list]
Ý nghĩa: Nhập một nội dung vào vùng nhớ ở địa chỉ address
Ví dụ:
Nhập vào 10 giá trị từ 1 đến 10 vào 10 byte bắt đầu ở địa chỉ 0B17:0100
-e 0b17:100 01 02 03 04 05 06 07 08 09 0a
Dùng lệnh D để kiểm tra lại:
-d 0b17:100
0B17:0100 01 02 03 04 05 06 07 08-09 0A 00 00 00 00 00 00
0B17:0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
Nhập vào chuỗi “Hello Assembly” vào vùng nhớ bắt đầu ở địa chỉ 0B17:0125:
-e 0b17:0125 "Hello Assembly"
-d 0b17:0100
7


0B17:0100 01 02 03 04 05 06 07 08-09 0A 00 00 00 00 00 00
0B17:0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0120 00 00 00 00 00 48 65 6C-6C 6F 20 41 73 73 65 6D Hello Assem
0B17:0130 62 6C 79 00 00 00 00 00-00 00 00 00 00 00 00 00 bly
0B17:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
Nhập tùy ý các byte vào vùng nhớ bắt đầu ở địa chỉ 0B17:0125:
-e 0b17:0125
0B17:0125 48._
Nhập giá trị mới vào, nhập xong nhấn SPACE BAR để chuyển sang byte kế tiếp.
1.3.5. Điền nội dung vùng nhớ (lệnh F)
Cú pháp: F range list
Ý nghĩa: Điền nội dung vào vùng nhớ ở địa chỉ address
Ví dụ:
Điền đầy chuỗi “Hello” vào vùng nhớ từ địa chỉ 0B17:0100 - 150
-f 0b17:100 150 "Hello"
-d 0b17:100
0B17:0100 48 65 6C 6C 6F 48 65 6C-6C 6F 48 65 6C 6C 6F 48 HelloHelloHelloH
0B17:0110 65 6C 6C 6F 48 65 6C 6C-6F 48 65 6C 6C 6F 48 65 elloHelloHelloHe
0B17:0120 6C 6C 6F 48 65 6C 6C 6F-48 65 6C 6C 6F 48 65 6C lloHelloHelloHel
0B17:0130 6C 6F 48 65 6C 6C 6F 48-65 6C 6C 6F 48 65 6C 6C loHelloHelloHell
0B17:0140 6F 48 65 6C 6C 6F 48 65-6C 6C 6F 48 65 6C 6C 6F oHelloHelloHello
0B17:0150 48 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 H
0B17:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
Điền đầy 22 33 vào vùng nhớ từ địa chỉ 0B17:0150 - 170
-f 0b17:150 200 22 33
-d 0b17:100

0B17:0100 48 65 6C 6C 6F 48 65 6C-6C 6F 48 65 6C 6C 6F 48 HelloHelloHelloH
0B17:0110 65 6C 6C 6F 48 65 6C 6C-6F 48 65 6C 6C 6F 48 65 elloHelloHelloHe
0B17:0120 6C 6C 6F 48 65 6C 6C 6F-48 65 6C 6C 6F 48 65 6C lloHelloHelloHel
0B17:0130 6C 6F 48 65 6C 6C 6F 48-65 6C 6C 6F 48 65 6C 6C loHelloHelloHell
0B17:0140 6F 48 65 6C 6C 6F 48 65-6C 6C 6F 48 65 6C 6C 6F oHelloHelloHello
0B17:0150 22 33 22 33 22 33 22 33-22 33 22 33 22 33 22 33 "3"3"3"3"3"3"3"3
0B17:0160 22 33 22 33 22 33 22 33-22 33 22 33 22 33 22 33 "3"3"3"3"3"3"3"3
0B17:0170 22 33 22 33 22 33 22 33-22 33 22 33 22 33 22 33 "3"3"3"3"3"3"3"3

1.3.6. Sao chép vùng nhớ (lệnh M)
Cú pháp: M range address
Ý nghĩa: Copy nội dung vùng nhớ đến địa chỉ address
Ví dụ:
Copy vùng nhớ 8 byte ở địa chỉ 0B17:500 đến địa chỉ 0B17:530
-d 0b17:500
0B17:0500 41 73 73 65 6D 62 6C 79-00 00 00 00 00 00 00 00 Assembly
0B17:0510 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0520 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0530 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0540 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0550 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0560 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0570 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
8

-m 0b17:500 507 0b17:0530
-d 0b17:500
0B17:0500 41 73 73 65 6D 62 6C 79-00 00 00 00 00 00 00 00 Assembly
0B17:0510 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0520 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00

0B17:0530 41 73 73 65 6D 62 6C 79-00 00 00 00 00 00 00 00 Assembly
0B17:0540 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0550 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0560 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0570 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
1.3.7. So sánh hai vùng nhớ (lệnh C)
Cú pháp: C range address
Ý nghĩa: So sánh nội dung vùng nhớ range và vùng nhớ bắt đầu ở địa chỉ address
Ví dụ:
So sánh hai vùng nhớ 8 byte ở địa chỉ 0B17:500 và 0B17:530
-C 0b17:500 507 0b17:530
0B17:0502 73 01 0B17:0532
-d 0b17:500
0B17:0500 41 73 73 65 6D 62 6C 79-00 00 00 00 00 00 00 00 Assembly
0B17:0510 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0520 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0530 41 73 01 65 6D 62 6C 79-00 00 00 00 00 00 00 00 As.embly
0B17:0540 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0550 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0560 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0570 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
1.3.8. Các thao tác đọc ghi file (lệnh N, L, W)
Cú pháp: N [pathname]
Ý nghĩa: Khai báo tên file muốn đọc hoặc ghi
Cú pháp: L [address] [drive]
Ý nghĩa: Nạp một file/ ổ đĩa lên bộ nhớ, sau khi nạp, giá trị 32bit chứa trong cặp thanh ghi
[BX|CX] cho biết kích thước file.
Cú pháp: W [address] [drive]
Ý nghĩa: Ghi một vùng nhớ vào file. Lưu ý, số byte cần ghi là giá trị 32bit chứa sẳn trong cặp
thanh ghi [BX|CX]

Chú ý: Không nên sử dụng lệnh W tùy tiện mà không biết tác động của nó như thế nào vì
có thể tạo các file không mong muốn hoặc hư hỏng dữ liệu trên đĩa.
Ví dụ: Giả sử có một file Text C:\aaa.txt có nội dung lớn hơn 30 ký tự. Đọc file text aaa.txt lên
vùng nhớ 0B17:0200 và sửa ký tự đầu tiên thành ‘*’ và ghi lại với tên file mới bbb.txt với nội dung
là 20 ký tự đầu tiên của file aaa.txt.
Khai báo tên file C:\aaa.txt :
-N C:\aaa.txt
Nạp file lên vị trí 0B17:0200 :
-L 0B17:0200
Xem lại nội dung file đã nạp 0B17:0200 :
-D 0b17:0200
0B17:0200 2A 65 73 74 0D 0A 31 32-33 0D 0A 48 65 6C 6C 6F Test 123 Hello
0B17:0210 0D 0A 41 73 73 65 6D 62-6C 79 00 00 00 00 00 00 Assembly
9

0B17:0220 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0230 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0240 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0250 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0260 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0270 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
Xem kích thước file trong cặp thanh ghi [BX|CX] :
-R
AX=0000 BX=0000 CX=001A DX=0516 SP=FFEE BP=0000 SI=0000 DI=0000
DS=17E1 ES=17E1 SS=17E1 CS=17E1 IP=0105 NV DN EI NG NZ NA PO NC
17E1:0105 0000 ADD [BX+SI],AL DS:0000=CD
Sửa ký tự đầu tiên :
-E 0B17:0200 '*'
Xem lại :
-D 0b17:0200

0B17:0200 2A 65 73 74 0D 0A 31 32-33 0D 0A 48 65 6C 6C 6F *est 123 Hello
0B17:0210 0D 0A 41 73 73 65 6D 62-6C 79 00 00 00 00 00 00 Assembly
0B17:0220 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0230 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0240 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0250 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0260 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0B17:0270 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
Khai báo tên file C:\bbb.txt :
-N C:\bbb.txt
Khai báo kích thước file sẽ ghi là 14h (20byte) :
-R BX
BX 0000
:
-R CX
CX 001A
:14
Ghi nội dung vùng nhớ bắt đầu ở địa chỉ 0B17:0200 :
-W 0B17:0200
Writing 00014 bytes
-
Bài tập: Tạo một file Hello.txt với nội dung là chuỗi Hello nằm liên tiếp. Kích thước file là 1KB. (Gợi
ý, dùng lệnh F để điền nội dung lên vùng nhớ trước)

×