© DHBK 2005
Công thức tính địa chỉ vật lí:
Thanh ghi chính
H +
*01
Thanh ghi phụ
+
Chỉ số dịch
Các thanh ghi sẽ mặc định đi với nhau kiểu:
Thanh ghi chính
:
Thanh ghi phụ
[
BP
+
3
]
=> thanh ghi phụ
BP
(
tra bảng trên sẽ thấy
SS
:
BP
)
, chỉ số dịch =
3
Địa chỉ vật lý =
SS
*01
H +
BP
+
3
=
0002H*01H + 0100H +
3
=
00020H + 0100H +
3
=
00123H
© DHBK 2005
TEST CX, CX
kiểm tra CX có bằng 0 không, thông báo bằng cờ ZF = 0 nếu khác 0
=
1 nếu bằng
0
JZ THOAT
nếu cờ ZF (Zezo Flag) = 1 thì nhảy đến nhãn
THOAT
còn không thì thực hiện lệnh tiếp theo
DEC CX
trừ CX đi 1
JMP LAP
nhảy đến nhãn
LAP
Tóm lại: Kiểm tra CX xem bằng 0 chưa, nếu chưa thì -1 rồi cứ thế đến bao giờ bằng 0 thì thoát vòng lặp
=>
While (CX !=
0)
CX-=CX;
lOMoARcPSD| 61554479
© DHBK 2005
CX = 2 => CL = 2, AX = 255d = 00FFh = 0000 0000 1111 1111 b
SAL
AX
,
CL
là dịch trái AX đi CL bit theo quy tắc:
=>
Dịch trái
0000 0000 1111 1111
đi
2
bit
Vậy AX =
0000 0011 1111 1100
(
Bài này thì không cần nhưng cũng nên để ý CF
=0)
Sau khi SAL
AX
,
CL
tiếp đến câu lệnh LOOP DICH
LOOP sẽ thực hiện CX = CX -1 rồi kiểm tra nếu CX
≠0
thì nhảy tới nhãn DICH
CX = 0 thì skip sang lệnh tiếp theo
Ở đây khi tới lệnh LOOP, CX = CX -1 = 2 –1 = 1
0
vậy nhảy tới nhãn DICH
SAL
AX
,
CL
với
AX
lúc này =
0000 0011 1111 1100
, CX sau lệnh LOOP = 1 =>
CL
=
1
Dịch trái
=>
0000 0011 1111 1100
đi
1
bit
Vậy
AX
=
0000 0111 1111 1000
b =
07
F
8
h =
2040
d
Ở đây khi tới lệnh LOOP, CX = CX -1 = 1 –1 = 0 vậy skip. AX ở trên chính là kết quả cuối
cùng của chương trình
lOMoARcPSD| 61554479
© DHBK 2005
DIV BX
sẽ chia AX cho BX, kết quả phép chia được lưu vào AX, số dư lưu vào DX
Nếu AX chia hết cho BX (Không có dư) => DX =
=>
0
CMP DX, 0
sẽ kiểm tra phần dư của phép chia có bằng 0 hay không (chia hết cho BX = 2)
TEST AX, 1
giống y hệt phép
AND AX, 1
nhưng kết quả sẽ không được lưu vào đâu mà chỉ
làm thay đổi 1 số thanh ghi cờ
AX = 0001 0110
VD:
TEST AX, 1 =>
Vậy hoàn toàn có thể xét ZF = 1 hay 0 để kết luận AX chia hết cho 2 hay không
TEST AL, 1
tương tự
1
TEST AX,
h
. Các bạn tự phân tíc
lOMoARcPSD| 61554479
© DHBK 2005
MSG DB 10 DUP(48)
là khai báo mảng tên MSG có 10 phần tử được Define Byte (DB) chiếm
1
byte bộ nhớ. Các phần tử này đều có giá trị 48 (48 = 30h
)
=>
MSG chứa 30h 30h 30h ... 30h (10 phần tử mỗi phần tử 1 byte
)
=>
Chiếm 10 byte
A DW 20, 120
là khai báo mảng tên A có các phần tử được Define Word (DW) chiếm 2 byte bộ
nhớ. A chứa 20 và 120 (2 phần tử mỗi phần tử 2 byte)
=>
Chiếm 2*2 byte = 4 byte
Tổng 14 byte
lOMoARcPSD| 61554479
© DHBK 2005
lOMoARcPSD| 61554479
© DHBK 2005
lOMoARcPSD| 61554479
© DHBK 2005
lOMoARcPSD| 61554479
© DHBK 2005
DS:DI => địa chỉ DS*01H+DI = A2C6h*01h+0B7Bh = A37DBh
=>
địa chỉ DS:DI+1 = A37DCh.
MOV AX,[DI+1]
sẽ lưu dữ liệu bắt đầu từ ô nhớ đó vào AX theo quy tắc byte thấp
vào AL, byte cao vào AH.
AX = 0403h
=>
A37E0h
XX
06
h
A37DFh
05
h
A37DEh
04
h
A37DDh
03
h
A37DCh
02
h
A37DBh
01
h
A37DAh
A37D9h
XX
DS:DI+1
AL
AH
04
h
03
h
lOMoARcPSD| 61554479
© DHBK 2005
LOOP sẽ thực hiện CX = CX - 1 rồi kiểm tra nếu CX
≠0
thì nhảy tới nhãn LAP
CX = 0 thì skip sang lệnh tiếp theo
Nhưng trong nhãn LAP, luôn đưa CL thành 2 trước khi LOOP nên sẽ không bao giờ thoả mãn
CX – 1 = 0. Vậy sẽ lặp vô tận, thanh ghi CX cũng sẽ bị thay đổi vô hạn lần
lOMoARcPSD| 61554479
© DHBK 2005
MOV AX, 0F978h
=>
AX = 0F978h = 1111 1001 0111 1000 b
=>
AH = 1111 1001 b AL = 0111 1000 b
SHL AH, 1
là dịch trái AH đi 1 bit theo quy tắc:
=>
AH = 1111 0010 b = F2h và cờ CF được dịch bit 1 từ MSB của AH vào => CF =
1
ADC AL, 02H
Add with Carry (cộng có nhớ).
=>
AL = AL + 02h + CF = 78h + 02h + 1 = 7Bh
=>
AX = F27Bh
Check code trên emu8086 ra kết quả y chang:
lOMoARcPSD| 61554479
© DHBK 2005
CMP AL, 39h
(
CoMPare
)
JA LABEL1
(
Jump Above
)
Tổ hợp 2 câu lệnh trên so sánh AL với 39h, nếu AL > 39h sẽ nhảy tới nhãn LABEL1 còn không
thì sẽ thực hiện những lệnh bên dưới
=>
IF (AL > 39h)... ELSE...
lOMoARcPSD| 61554479
© DHBK 2005
MOV AX, 0F0F1h
=>
AX = F0F1h = 1111 0000 1111 0001b
SHL AX, 1
là dịch trái AX đi 1 bit theo quy tắc:
=>
AX = 1110 0001 1110 0010 hay AH = 1110 0001 b = E1h, AL = 1110 0010 b = E2h
và CF nhận 1 từ MSB của AX => CF = 1
ADC AH, 1
là cộng có nhớ (ADd with Carry)
=>
AH = AH + 1 + CF = E1h + 1 + 1 = E3h
=>
Sau các lệnh trên, AX = E3E2h
Check code trên emu8086 ra kết quả như phân tích ở trên, uy tín luôn
lOMoARcPSD| 61554479
© DHBK 2005
CX = 0100h => CH = 01h, CL = 00h
MOV CL, 2
=>
CL = 2 => CX = 0102h = 258 (CX thay đổi giá trị 1 lần
)
LOOP sẽ thực hiện CX = CX - 1 rồi kiểm tra nếu CX
≠0
thì nhảy tới nhãn LAP
CX = 0 thì skip sang lệnh tiếp theo
=>
sau 258 lần LOOP, thanh ghi CX giảm tới 0 và skip k LOOP nữa (CX thay đổi giá trị 258 lần
)
=>
Tổng
259
lOMoARcPSD| 61554479
© DHBK 2005
MOV BX, AX
=>
BX = AX lúc đầu, tạm đặt AX lúc đầu là Q => BX = Q
SHL AX, CL
=>
có 2 trường hợp
:
Nếu phép dịch trái n bit không gây tràn thì giá trị sau khi dịch sẽ gấp 2^n giá trị trước đó
Nếu phép dịch có tràn thì chịu chết, k so sánh được giá trị
VD:
AX = 0000 0000 0000 0010 b = 2
Dịch trái 3 bit => AX = 0000 0000 0001 0000 b = 16 gấp 2^3 = 8 lần giá trị ban đầu
AX = 1000 0000 0000 0001 b = 32769
Dịch trái 1 bit => AX = 0000 0000 0000 0010 = 2 ???
Nhưng vì ở đây có điều kiện AX < 1000 = 03E8h = 0000 0011 1110 1000 nên dịch trái thoải mái 5
6
bit thì giá trị vẫn gấp 2^n lần theo quy luật
=>
SHL AX, CL sẽ làm AX gấp 2^CL lần AX lúc đầu, với CL = 2 => sau lệnh trên, AX = 4 Q
ADD AX, BX
=>
AX = AX + BX = 4Q + Q = 5 Q
=>
sau các lệnh trên, AX đã gấp 5 lần AX lúc đầu (VALUE
)
lOMoARcPSD| 61554479
© DHBK 2005
lOMoARcPSD| 61554479
© DHBK 2005
XOR AX, AX
đưa AX về 0
INC AL
tăng giá trị thanh ghi ALn 1 đơn vị
ADD AH, AL
=>
AH = AH + AL
CMP AL, 9
JNE LAP
(
Jump if Not Equal
)
2
câu lệnh này so sánh AL với 9 rồi nếu AL != 9 thì nhảy tới nhãn LAP, AL = 9 thì skip
=>
Đây là chương trình tính tổng chuỗi 1+2+3+...+9 và lưu vào AH
=>
AH =
45
Test code emu8086 ra AH = 2Dh = 45 chuẩn rồi
lOMoARcPSD| 61554479
© DHBK 2005
lOMoARcPSD| 61554479
© DHBK 2005
Khai báo các biến x, N, res, i kiểu int (2 byte = DW trong asm)
mảng A chứa N các phần tử int
Res = -1
i = N-1
Code ở phần note trong slide này,
copy paste vào emu8086 mà nghịch thử n
lOMoARcPSD| 61554479

Preview text:

© DHBK 2005
Công thức tính địa chỉ vật lí: Thanh ghi chính H + *01
Thanh ghi phụ + Chỉ số dịch
Các thanh ghi sẽ mặc định đi với nhau kiểu:
Thanh ghi chính : Thanh ghi phụ
[ BP + 3 ] => thanh ghi phụ BP ( tra bảng trên sẽ thấy SS : BP ) , chỉ số dịch = 3 Địa chỉ vật lý = SS *01 H + BP + 3 = 0002H*01H + 0100H + 3 = 00020H + 0100H + 3 = 00123H lOMoAR cPSD| 61554479 © DHBK 2005
TEST CX, CX kiểm tra CX có bằng 0 không, thông báo bằng cờ ZF = 0 nếu khác 0 = 1 nếu bằng 0
JZ THOAT nếu cờ ZF (Zezo Flag) = 1 thì nhảy đến nhãn THOAT còn không thì thực hiện lệnh tiếp theo DEC CX trừ CX đi 1
JMP LAP nhảy đến nhãn LAP
Tóm lại: Kiểm tra CX xem bằng 0 chưa, nếu chưa thì -1 rồi cứ thế đến bao giờ bằng 0 thì thoát vòng lặp => While (CX != 0) CX-=CX; lOMoAR cPSD| 61554479 © DHBK 2005
CX = 2 => CL = 2, AX = 255d = 00FFh = 0000 0000 1111 1111 b
SAL AX , CL là dịch trái AX đi CL bit theo quy tắc: =>
Dịch trái 0000 0000 1111 1111 đi 2 bit Vậy AX =
0000 0011 1111 1100 ( Bài này thì không cần nhưng cũng nên để ý CF =0)
Sau khi SAL AX , CL tiếp đến câu lệnh LOOP DICH
LOOP sẽ thực hiện CX = CX -1 rồi kiểm tra nếu CX ≠0 thì nhảy tới nhãn DICH
CX = 0 thì skip sang lệnh tiếp theo
Ở đây khi tới lệnh LOOP, CX = CX -1 = 2 –1 = 1 ≠ 0 vậy nhảy tới nhãn DICH SAL
AX , CL với AX lúc này = 0000 0011 1111 1100 , CX sau lệnh LOOP = 1 => CL = 1 =>
Dịch trái 0000 0011 1111 1100 đi 1 bit Vậy
AX = 0000 0111 1111 1000 b = 07 F 8 h = 2040 d
Ở đây khi tới lệnh LOOP, CX = CX -1 = 1 –1 = 0 vậy skip. AX ở trên chính là kết quả cuối cùng của chương trình lOMoAR cPSD| 61554479 © DHBK 2005
DIV BX sẽ chia AX cho BX, kết quả phép chia được lưu vào AX, số dư lưu vào DX
=> Nếu AX chia hết cho BX (Không có dư) => DX = 0
CMP DX, 0 sẽ kiểm tra phần dư của phép chia có bằng 0 hay không (chia hết cho BX = 2)
TEST AX, 1 giống y hệt phép AND AX, 1 nhưng kết quả sẽ không được lưu vào đâu mà chỉ
làm thay đổi 1 số thanh ghi cờ VD: AX = 0001 0110 TEST AX, 1 =>
Vậy hoàn toàn có thể xét ZF = 1 hay 0 để kết luận AX chia hết cho 2 hay không
TEST AL, 1 tương tự TEST AX, 1
. Các bạn tự phân tích lOMoAR cPSD| 61554479 © DHBK 2005
MSG DB 10 DUP(48) là khai báo mảng tên MSG có 10 phần tử được Define Byte (DB) chiếm
1 byte bộ nhớ. Các phần tử này đều có giá trị 48 (48 = 30h )
=> MSG chứa 30h 30h 30h ... 30h (10 phần tử mỗi phần tử 1 byte ) => Chiếm 10 byte
A DW 20, 120 là khai báo mảng tên A có các phần tử được Define Word (DW) chiếm 2 byte bộ
nhớ. A chứa 20 và 120 (2 phần tử mỗi phần tử 2 byte)
=> Chiế m 2*2 byte = 4 byte Tổng 14 byte lOMoAR cPSD| 61554479 © DHBK 2005 lOMoAR cPSD| 61554479 © DHBK 2005 lOMoAR cPSD| 61554479 © DHBK 2005 lOMoAR cPSD| 61554479 © DHBK 2005
DS:DI => địa chỉ DS*01H+DI = A2C6h*01h+0B7Bh = A37DBh
=> địa chỉ DS:DI+1 = A37DCh.
MOV AX,[DI+1] sẽ lưu dữ liệu bắt đầu từ ô nhớ đó vào AX theo quy tắc byte thấp vào AL, byte cao vào AH. XX A37E0h 06 AH AL h A37DFh 04 05 h 03 h h A37DEh 04 h A37DDh DS:DI+1 03 h A37DCh 02 h A37DBh 01 h A37DAh => AX = 0403h XX A37D9h lOMoAR cPSD| 61554479 © DHBK 2005
LOOP sẽ thực hiện CX = CX - 1 rồi kiểm tra nếu CX ≠0 thì nhảy tới nhãn LAP
CX = 0 thì skip sang lệnh tiếp theo
Nhưng trong nhãn LAP, luôn đưa CL thành 2 trước khi LOOP nên sẽ không bao giờ thoả mãn
CX – 1 = 0. Vậy sẽ lặp vô tận, thanh ghi CX cũng sẽ bị thay đổi vô hạn lần lOMoAR cPSD| 61554479 © DHBK 2005
MOV AX, 0F978h => AX = 0F978h = 1111 1001 0111 1000 b
=> AH = 1111 1001 b AL = 0111 1000 b
SHL AH, 1 là dịch trái AH đi 1 bit theo quy tắc:
=> AH = 1111 0010 b = F2h và cờ CF được dịch bit 1 từ MSB của AH vào => CF = 1
ADC AL, 02H là Add with Carry (cộng có nhớ).
=> AL = AL + 02h + CF = 78h + 02h + 1 = 7Bh => AX = F27Bh
Check code trên emu8086 ra kết quả y chang: lOMoAR cPSD| 61554479 © DHBK 2005 CMP AL, 39h ( CoMPare ) JA LABEL1 ( Jump Above )
Tổ hợp 2 câu lệnh trên so sánh AL với 39h, nếu AL > 39h sẽ nhảy tới nhãn LABEL1 còn không
thì sẽ thực hiện những lệnh bên dưới
=> IF (AL > 39h)... ELSE... lOMoAR cPSD| 61554479 © DHBK 2005
MOV AX, 0F0F1h => AX = F0F1h = 1111 0000 1111 0001b
SHL AX, 1 là dịch trái AX đi 1 bit theo quy tắc:
=> AX = 1110 0001 1110 0010 hay AH = 1110 0001 b = E1h, AL = 1110 0010 b = E2h
và CF nhận 1 từ MSB của AX => CF = 1
ADC AH, 1 là cộng có nhớ (ADd with Carry)
=> AH = AH + 1 + CF = E1h + 1 + 1 = E3h
=> Sau các lệnh trên, AX = E3E2h
Check code trên emu8086 ra kết quả như phân tích ở trên, uy tín luôn lOMoAR cPSD| 61554479 © DHBK 2005
CX = 0100h => CH = 01h, CL = 00h
MOV CL, 2 => CL = 2 => CX = 0102h = 258 (CX thay đổi giá trị 1 lần )
LOOP sẽ thực hiện CX = CX - 1 rồi kiểm tra nếu CX ≠0 thì nhảy tới nhãn LAP
CX = 0 thì skip sang lệnh tiếp theo
=> sau 258 lần LOOP, thanh ghi CX giảm tới 0 và skip k LOOP nữa (CX thay đổi giá trị 258 lần ) => Tổng 259 lOMoAR cPSD| 61554479 © DHBK 2005
MOV BX, AX => BX = AX lúc đầu, tạm đặt AX lúc đầu là Q => BX = Q
SHL AX, CL => có 2 trường hợp :
Nếu phép dịch trái n bit không gây tràn thì giá trị sau khi dịch sẽ gấp 2^n giá trị trước đó
Nếu phép dịch có tràn thì chịu chết, k so sánh được giá trị VD:
AX = 0000 0000 0000 0010 b = 2
Dịch trái 3 bit => AX = 0000 0000 0001 0000 b = 16 gấp 2^3 = 8 lần giá trị ban đầu
AX = 1000 0000 0000 0001 b = 32769
Dịch trái 1 bit => AX = 0000 0000 0000 0010 = 2 ???
Nhưng vì ở đây có điều kiện AX < 1000 = 03E8h = 0000 0011 1110 1000 nên dịch trái thoải mái 5
6 bit thì giá trị vẫn gấp 2^n lần theo quy luật
=> SHL AX, CL sẽ làm AX gấp 2^CL lần AX lúc đầu, với CL = 2 => sau lệnh trên, AX = 4 Q
ADD AX, BX => AX = AX + BX = 4Q + Q = 5 Q =>
sau các lệnh trên, AX đã gấp 5 lần AX lúc đầu (VALUE ) lOMoAR cPSD| 61554479 © DHBK 2005 lOMoAR cPSD| 61554479 © DHBK 2005 XOR AX, AX đưa AX về 0
INC AL tăng giá trị thanh ghi AL lên 1 đơn vị ADD AH, AL => AH = AH + AL CMP AL, 9 JNE LAP ( Jump if Not Equal )
2 câu lệnh này so sánh AL với 9 rồi nếu AL != 9 thì nhảy tới nhãn LAP, AL = 9 thì skip
=> Đây là chương trình tính tổng chuỗi 1+2+3+...+9 và lưu vào AH => AH = 45
Test code emu8086 ra AH = 2Dh = 45 chuẩn rồi lOMoAR cPSD| 61554479 © DHBK 2005 lOMoAR cPSD| 61554479 © DHBK 2005
Khai báo các biến x, N, res, i kiểu int (2 byte = DW trong asm)
mảng A chứa N các phần tử int Res = -1 i = N-1
Code ở phần note trong slide này,
copy paste vào emu8086 mà nghịch thử nhé