เว็บไซต์บุคลากรภาควิชา...
Transcript of เว็บไซต์บุคลากรภาควิชา...
1
7
CS344-321 Assembly Language Programming chapter 5 page
________________________________________________________________________
Chapter 5
Arithmetic Instructions
5.1 Introduction
5.1.1 Processing unsigned and signed data
For unsigned data, where all bits are intended to be data bits, a 16-bit register can contain a maximum of 65,535. For signed data, where the leftmost bit is a sign bit, the register can contain a maximum of 32,767. But note that the ADD and SUB instructions do not distinguish between unsigned and signed data and, indeed, simply add and subtract bits.
Example,
a) no carry or overflow
unsignedsigned
binary
decimal
decimal
OFCF
11111001249
-7
+ 00000010 2
+2
11111011251
-5
00
b) arithmetic carry
unsignedsigned
binary
decimal
decimal
OFCF
11111100252
-4
+ 00000101 5
+5
(1)00000001 1
+1
01
(invalid)
(valid)
c) overflow
unsignedsigned
binary
decimal
decimal
OFCF
01111001121
+121
+ 00001011 11
+11
10000100 132
-124
10
(valid)
(invalid)
d) carry and overflow
unsignedsigned
binary
decimal
decimal
OFCF
11110110246
-10
+ 10001001137
-119
(1)01111111127
+127
11
(invalid)
(invalid)
5.1.2 Data in decimal format
The 8086/8088 also supports Binary-Coded Decimal (BCD) format. A BCD digit consists of four bits that represent the decimal digits 0 through 9:
BinaryBCD digit
BinaryBCD digit
00000
01015
00011
01106
00102
01117
00113
10008
01004
10019
You can store BCD digits as unpacked or as packed:
( Unpacked BCD contains a single BCD digit in the lower (rightmost) four bits of each byte, with zeros in the upper four bits. Note that althrough ASCII format is also in a sense “unpacked,” it isn’t called that.
( Packed BCD contains two BCD digits, one in the upper four bits and one in the lower four bits.
Example, Let’s examine the representation of the decimal number 1,527 in the three decimal formats:
Format
Contents
Length
ASCII
31h 35h 32h 37h4 bytes
Unpacked BCD01h 05h 02h 07h
4 bytes
Packed BCD15h 27h
2 bytes
Note!
· processing ASCII and unpacked BCD see AAA for addition, AAS for subtraction
· processing unpacked BCD data see AAM for multiplication, AAD for division
· processing packed BCD data see DAA for addition, DAS for subtraction
5.2 Arithmetic Instructions
mnemonicassembler format
flags
OF DF IF TF SF ZF AF PF CF
Addition
addadd destination,source
* - - - * * * * *
adcadc destination,source
* - - - * * * * *
aaaaaa
? - - - ? ? * ? *
daadaa
? - - - * * * * *
incinc destination
* - - - * * * * -
Subtraction
subsub destination,source
* - - - * * * * *
sbbsbb destination,source
* - - - * * * * *
aasaas
? - - - ? ? * ? *
dasdas
? - - - * * * * *
decdec destination
* - - - * * * * -
negneg destination
* - - - * * * * *
cmpcmp destination,source
* - - - * * * * *
Multiplication
mulmul source
* - - - ? ? ? ? *
imulimul source
* - - - ? ? ? ? *
aamaam
? - - - * * ? * ?
Division
divdiv source
? - - - ? ? ? ? ?
idividiv source
? - - - ? ? ? ? ?
aadaad
? - - - * * ? * ?
Sign-Extension
cbwcbw
- - - - - - - - -
cwdcwd
- - - - - - - - -
Note! * means changed, – means unchanged, and ? means undefined
5.2.1 Addition
ADD : Add Binary Numbers
Operation. Adds binary values from memory, register, or immediate to a register, or adds values in a register or immediate to memory. Values may be byte or word.
Note! มีผลกับค่า flags ดังนี้
· CF มีค่า 0 ถ้าผลลัพธ์ไม่มีการทดค่า
มีค่า 1 ถ้าผลลัพธ์มีการทดค่า
· PF มีค่า 0 ถ้าผลลัพธ์มีจำนวนบิตที่มีค่า 1 เป็นคี่
มีค่า 1 ถ้าผลลัพธ์มีจำนวนบิตที่มีค่า 1 เป็นคู่
· AF มีค่า 0 ถ้าผลการบวกเลขฐานสิบไม่ต้องปรับค่า (พิจารณาเฉพาะการทดค่าจากบิต 3 ไป 4 ของ AL)
มีค่า 1 ถ้าผลการบวกเลขฐานสิบต้องปรับค่า (พิจารณาเฉพาะการทดค่าจากบิต 3 ไป 4 ของ AL)
· ZF มีค่า 0 ถ้าผลลัพธ์ไม่ใช่ 0
มีค่า 1 ถ้าผลลัพธ์เป็น 0
· SFมีค่า 0 ถ้าผลลัพธ์มีค่าบวก
มีค่า 1 ถ้าผลลัพธ์มีค่าลบ
· OFมีค่า 1 ถ้าเป็นการบวกเลขที่ sign bit เหมือนกัน แต่ให้ผลลัพธ์ที่มี sign bit เปลี่ยนไป มิฉะนั้นจะมีค่าเป็น 0
Source Code. ADD {register/memory},{register/memory/immediate}
Object Code. (three formats)
Reg/mem with reg: |000000dw|modregr/m|
Immed to accumu’r: |0000010w|---data---|data if w=1|
Immed to reg/mem:|100000sw|mod000r/m|---data---|data if sw=01|
ตัวอย่าง พิจารณาการบวกเลขฐาน 2 ต่อไปนี้
; AL = 01110011 = 115 decimal
; BL = 00010010 = 18 decimal
addal,bl; al เก็บผลลัพธ์ = 10000101 , bl unchanged
;CF = 0, AF = 0, ZF = 0, SF = 1, OF = 1, PF = 0
sign bit
; unsigned addition valid signed addition invalid
bit7654 3210
AL0111 0011 operands have the same sign (i.e. 0)
BL0001 0010 sign bit changed (from 0 to 1) OF = 1
AL1000 0101 # of 1 is odd PF = 0, bit 7 is 1 so SF =1, result ( 0 so ZF = 0
0 0
CF AF
คำสั่ง ADD จะบวกเลขฐาน 2 ดังกล่าวข้างต้นเสมอ ท่านผู้ซึ่งเป็นคนเขียนโปรแกรมต้องตีความเองว่า ท่านกำลังบวกเลขที่มีเครื่องหมายหรือไม่มีเครื่องหมาย ถ้าท่านบวกเลขที่มีเครื่องหมาย ท่านจะตรวจสอบว่าผลลัพธ์ overflow ได้โดยตรวจสอบจาก OF = 1 ได้ เช่น ตัวอย่างข้างต้น (+115) + (+18) = +133 ซึ่งมีค่าเกิน +127 ซึ่งถ้าดูจากผลลัพธ์แล้ว 1000 0101 มีค่าเท่ากับ –123 ซึ่งไม่ถูกต้อง แต่ถ้าท่านบวกเลขที่ไม่มีเครื่องหมาย ท่านจะตรวจสอบว่าผลลัพธ์ overflow ได้โดยตรวจสอบจาก OF = 1 ไม่ได้ เพราะถ้าดูจากตัวอย่างข้างต้น 115 + 18 = 133 ซึ่งมีค่าไม่เกิน 255 ซึ่งถ้าดูจากผลลัพธ์แล้ว 1000 0101 มีค่าเท่ากับ 133 ซึ่งถูกต้อง การตรวจสอบว่าการบวกเลขที่ไม่มีเครื่องหมายเกิด overflow หรือไม่ให้ดูที่ CF = 1 หรือไม่ เช่น
; AL = 11111111 , unsigned = 255 decimal, signed = -1
; BL = 00000001 , unsigned = 1 decimal , signed = +1 decimal
addal,bl; al เก็บผลลัพธ์ = 00000000 , bl unchanged
;CF = 1, AF = 1, ZF = 1, SF = 0, OF = 0, PF = 1
; unsigned addition invalid signed addition valid
sign bit
bit7654 3210
AL1111 1111 operands have the different sign OF = 0
BL0000 0001
AL0000 0000 # of 1 is even PF = 1, bit 7 is 0 so SF =0, result = 0 so ZF = 1
1 1
CF AF
ADC : Add with Carry
Operation. Typically used in multiword binary addition to carry an overflowed 1-bit into the next stage of arithmetic. If the CF flag is set, ADC first adds 1 to operand 1. ADC then adds operand 2 to operand 1, just as ADD does.
Source Code. ADC {register/memory},{register/memory/immediate}
Object Code. (three formats)
Reg/mem with reg: |000100dw|modregr/m|
Immed to accumu’r: |0001010w|---data---|data if w=1|
Immed to reg/mem:|100000sw|mod010r/m|---data---|data if sw=01|
หมายเหตุ เหมือน ADD แต่บวก carry flag(CF) ด้วย คือ destination = destination + carry + source
ตัวอย่าง
addax,cx
adcbx,dx
ADC BX,DX
ADD AX,CX
CF
BX
AX
DX
CX
BX AX
ตัวอย่าง
; 32 bits integer addition
; z = x+y
dosseg
.model small
.stack 1024
.data
x dd 12345678h
y dd 9abcdef0h
z dd ?
.code
start:
mov ax,@data
mov ds,ax
mov ax,word ptr x
add ax,word ptr y
mov word ptr z,ax
mov ax,word ptr x+2
adc ax,word ptr y+2
mov word ptr z+2,ax
mov ax,4c00h
int 21h
end start
AAA : ASCII Adjust for Addition
Operation. Corrects the sum of two ASCII bytes in the AL. If the rightmost four bits of the AL have a value greater than 9 or if the AF flag is set to 1, AAA adds 1 to the AH and sets the AF and CF flags. Otherwise, the AF and CF are cleared. AAA always clears the leftmost four bits of the AL.
Source Code. AAA
Object Code. 00110111
สมมุติว่าเราต้องการบวกตัวเลข ASCII 8 (38H) และ 4 (34H)
00111000(ASCII 38H)
+ (ใช้คำสั่ง ADD)
00110100(ASCII 34H)
01101100(6CH)
จะเห็นได้ว่าผลลัพธ์ที่ได้ไม่เป็นไปตามที่เราคาดหวัง เราคาดหวังว่าจะได้ ASCII 1 (31H) ASCII 2 (32H) หรือ 12 (3132H) คำสั่ง AAA และ OR (จะกล่าวในบทถัดไป) จะช่วยเราในเรื่องนี้
คำสั่ง AAA ไม่มี operand ใช้เพื่อปรับค่าในเรจิสเตอร์ AX เท่านั้น โดยการพิจารณาค่า 4 บิตล่างของ AL ถ้ามีค่าระหว่าง 0-9 ก็จะทำให้ 4 บิตบนของ AL มีค่าเป็น 0 และกำหนดให้ AF กับ CF มีค่าเป็น 0 แต่ถ้า 4 บิตล่างของ AL มีค่ามากกว่า 9 หรือ AF มีค่า 1 จะมีวิธีการปรับค่า ดังนี้
· บวก 6 กับเรจิสเตอร์ AL เลข 6 มาจาก 16 (hexadecimal) – 10 (decimal)
· บวก 1 กับเรจิสเตอร์ AH
· กำหนดให้ AF = 1 และ CF = 1
· 4 บิตบนของเรจิสเตอร์ AL มีค่า 0
หมายเหตุ ถ้าต้องการเก็บตัวทดใน AH ก่อนใช้คำสั่ง AAA ทำ AH ให้เป็น 0 แล้วใช้คำสั่งบวกที่มี AL เป็น destination ก่อน
ตัวอย่าง
a)
; AH = 0 AL = 34H (ASCII 4)
; BL = 38H (ASCII 8)
MOVAX,0034H; AH = 0, AL = 34H
MOVBL,38H
ADD AL,BL
; add 34H with 38H, AX equals 006CH
AAA
; เนื่องจาก 4 บิตล่างของ AL มีค่ามากกว่า 9 บวก 6 กับ AL บวก 1 กับ AH
; กำหนดให้ CF = 1 และ AF = 1 แล้วทำให้ 4 บิตบนของ AL มีค่าเท่ากับ 0
; ผลสุดท้าย AX = 0102H
b)
; AL = 39H (ASCII 9)
MOVAX,0039H; AH = 0, AL = 39H
ADD AL,AL
; add 39H with 39H, AX equals 0072H, AF = 1
AAA
; เนื่อง AF = 1 แม้ค่าจาก 4 บิตล่างของ AL มีค่าน้อยกว่า 9 บวก 6 กับ AL
; บวก 1 กับ AH
; กำหนดให้ CF = 1 และ AF = 1 แล้วทำให้ 4 บิตบนของ AL มีค่าเท่ากับ 0
; ผลสุดท้าย AX = 0108H
จะเห็นได้ว่าทั้งสองตัวอย่างข้างต้น ยังไม่ได้ค่า 3132H หรือ 3138H ตามที่เราต้องการ จะต้องใช้คำสั่ง
ORAX,3030H จึงจะได้ค่าตามที่ต้องการ ดังนั้นชื่อของ AAA (ASCII Adjust for Addition) ที่ใช้ อาจจะทำให้เข้าใจผิดได้ง่าย จริง ๆ แล้วคำสั่ง AAA เป็นแค่การปรับค่าของการบวก Unpacked BCD เท่านั้น น่าจะมีชื่อเป็น Unpacked BCD Adjust for Addition
สรุปแล้ว AAA ใช้ได้ทั้งการปรับค่าของการบวก ASCII และ Unpacked BCD แต่ถ้าเป็นการบวกของ ASCII และต้องการให้ผลลัพธ์เก็บอยู่ในรูป ASCII ต้องใช้คำสั่ง OR AX,3030H เพิ่มอีกคำสั่งหนึ่ง
DAA : Decimal Adjust for Addition
Operation. Corrects the result of adding two BCD (packed decimal) items in the AL. If the rightmost four bits have a value greater than 9 or the AF flag is 1, DAA adds 6 to the AL and sets the AF. If the leftmost four bits have a value greater than 9 or the CF flag is 1, DAA adds 60h to the AL and sets the CF.
Source Code. DAA
Object Code. 00100111
DAA ใช้สำหรับปรับค่าของการบวก packed BCD วิธีการปรับค่าของคำสั่ง DAA ทำดังนี้
· ถ้า 4 บิตล่างของเรจิสเตอร์ AL มีค่ามากกว่า 9 หรือ AF = 1 จะบวกค่า 6 กับเรจิสเตอร์ AL และกำหนดให้ AF = 1
· ถ้า 4 บิตบนของเรจิสเตอร์ AL มีค่ามากกว่า 9 หรือ CF = 1 จะบวกค่า 60h กับเรจิสเตอร์ AL และกำหนดให้ CF = 1
ตัวอย่าง
ก. ผลลัพธ์เก็บใน AL พอ
; AL = 0101 1001 = 59 BCD
; BL = 0011 0101 = 35 BCD
ADD AL,BL; AL =1000 1110 = 8EH incorrect
DAA
; AL = 1001 0100 = 94 BCD
AL
0101 100159H
BL
0011 010135H
ADD AL,BL
AL
1000 11108EH
CF = 0 AF = 0
DAA
AL
1000 1110
0000 01106H because AH > 9 add 6 to AL and set AF = 1
AL
1001 010094H
ข. ผลลัพธ์เก็บใน AL ไม่พอ (หลังจากทำคำสั่ง DAA ดู CF =1)
; AL = 1000 1000 = 88 BCD
; BL = 0100 1001 = 49 BCD
MOVAX,88H
MOVBL,49H
ADD AL,BL; AL =1101 0001 , AF = 1
DAA
; add 0110 because AF = 1
; AL = 1101 0111 = D7H
; 1101 > 9 add 0110 0000
; CF = 1 and AL = 0011 0111 = 37
ADCAH,0; AX = 0000 0001 0011 0111 = 0137 BCD
INC : Increment by 1
Operation. Increments by 1 a byte, or word in a register or memory, coded, for example, as INC CX.
Source Code. INC {register/memory}
Object Code. (two formats)
Register:|01000reg|
Reg/memory:|1111111w|mod000r/m|
หมายเหตุ คำสั่งนี้ไม่มีผลกับ CF
5.2.2 Subtraction
SUB : Subtract Binary Numbers
Operation. Subtract binary values in a register, memory, or immediate from a register, or subtracts values in a register or immediate from a memory. Values may be byte or word.
Note! มีผลกับค่า flags ดังนี้
· CF มีค่า 0 ถ้าผลลัพธ์ไม่มีการขอยืมค่า
มีค่า 1 ถ้าผลลัพธ์มีการขอยืมค่า
· PF มีค่า 0 ถ้าผลลัพธ์มีจำนวนบิตที่มีค่า 1 เป็นคี่
มีค่า 1 ถ้าผลลัพธ์มีจำนวนบิตที่มีค่า 1 เป็นคู่
· AF มีค่า 0 ถ้าผลการบวกเลขฐานสิบไม่ต้องปรับค่า (พิจารณาเฉพาะการยืมค่าจากบิต 4 ของ AL)
มีค่า 1 ถ้าผลการบวกเลขฐานสิบต้องปรับค่า (พิจารณาเฉพาะการยืมค่าจากบิต 4 ของ AL)
· ZF มีค่า 0 ถ้าผลลัพธ์ไม่ใช่ 0
มีค่า 1 ถ้าผลลัพธ์เป็น 0
· SFมีค่า 0 ถ้าผลลัพธ์มีค่าบวก
มีค่า 1 ถ้าผลลัพธ์มีค่าลบ
· OFมีค่า 1 ถ้าการลบเลขที่มีเครื่องหมายต่างกันให้ผลลัพธ์ที่ใหญ่หรือเล็กกว่าที่จะเก็บได้ เช่น ลบเลขขนาด 8 บิต ได้ผลลัพธ์น้อยกว่า –128 หรือมากกว่า 127 เป็นต้น
Source Code. SUB {register/memory},{register/memory/immediate}
Object Code. (three formats)
Reg/mem with reg: |001010dw|modregr/m|
Immed to accumu’r: |0010110w|---data---|data if w=1|
Immed to reg/mem:|100000sw|mod101r/m|---data---|data if sw=01|
ตัวอย่าง
; AL = 01110011 = signed +115 decimal = unsigned 115 decimal
; BL = 11101110 = signed -18 decimal = unsigned 238 decimal
subal,bl; al เก็บผลลัพธ์ = 10000101 , bl unchanged
;CF = 1, AF = 1, ZF = 0, SF = 1, OF = 1, PF = 0
sign bit
; unsigned subtraction invalid signed subtraction invalid
bit7654 3210
AL0111 0011 operands have the different sign
BL1110 1110 for signed result can not fit so OF = 1
AL1000 0101 # of 1 is odd PF = 0, bit 7 is 1 so SF =1, result ( 0 so ZF = 0
1 1
CF AF
คำสั่ง SUB ก็เหมือนกับคำสั่ง ADD จะลบเลขฐาน 2 ดังกล่าวข้างต้นเสมอ ท่านผู้ซึ่งเป็นคนเขียนโปรแกรมต้องตีความเองว่า ท่านกำลังลบเลขที่มีเครื่องหมายหรือไม่มีเครื่องหมาย ถ้าท่านลบเลขที่มีเครื่องหมาย ท่านจะตรวจสอบว่าผลลัพธ์ overflow ได้โดยตรวจสอบจาก OF = 1 ได้ เช่น ตัวอย่างข้างต้น (+115) - (-18) = +133 ซึ่งมีค่าเกิน +127 ซึ่งถ้าดูจากผลลัพธ์แล้ว 1000 0101 มีค่าเท่ากับ –123 ซึ่งไม่ถูกต้อง แต่ถ้าท่านลบเลขที่ไม่มีเครื่องหมาย ท่านจะตรวจสอบว่าผลลัพธ์ overflow ได้โดยตรวจสอบจาก OF = 1 ไม่ได้ เพราะถ้าดูจากตัวอย่างข้างต้น 115 - 238 = -123 ซึ่งไม่ถูกต้อง (เพราะผลลัพธ์ 1000 0101 = 133) การตรวจสอบว่าการลบเลขที่ไม่มีเครื่องหมายให้ผลลัพธ์ที่ถูกต้องหรือไม่ให้ดูที่ CF = 1 หรือไม่
SBB : Subtract with Borrow
Operation. Typically used in multiword binary subtraction to carry an overflowed 1-bit into the next stage of arithmetic. If the CF flag is set, SBB first subtract 1 from operand 1. SBB always subtracts operand 2 from operand 1, just like SUB.
Source Code. SBB {register/memory},{register/memory/immediate}
Object Code. (three formats)
Reg/mem with reg: |000110dw|modregr/m|
Immed to accumu’r: |0001110w|---data---|data if w=1|
Immed to reg/mem:|100000sw|mod011r/m|---data---|data if sw=01|
หมายเหตุ เหมือน SUB แต่รวม carry flag(CF) ด้วย คือ destination = destination – carry - source
ตัวอย่าง
subax,cx
sbbbx,dx
SBB BX,DX
SUB AX,CX
BX
CF
AX
CX
DX
BX AX
AAS : ASCII Adjust for Subtraction
Operation. Corrects subtraction of two ASCII bytes in the AL. If the rightmost four bits of the AL have a value greater than 9 or if the CF flag is 1, AAS subtracts 6 from the AL, subtracts 1 from the AH, and sets the AF and CF flags. Otherwise, the AF and CF are cleared. AAS always clears the leftmost four bits of the AL.
Source Code. AAS
Object Code. 00111111
ใช้สำหรับการปรับค่าการลบเลข ASCII หรือ Unpacked BCD เหมือนกับที่มีการปรับค่าของคำสั่ง AAA
คำสั่ง AAS จะปรับค่า โดยการพิจารณาค่า 4 บิตล่างของ AL ถ้ามีค่าระหว่าง 0-9 ก็จะทำให้ 4 บิตบนของ AL มีค่าเป็น 0 และกำหนดให้ AF กับ CF มีค่าเป็น 0 แต่ถ้า 4 บิตล่างของ AL มีค่ามากกว่า 9 หรือ AF มีค่า 1 จะมีวิธีการปรับค่า ดังนี้
· ลบ 6 จากเรจิสเตอร์ AL
· ลบ 1 จากเรจิสเตอร์ AH
· AF = 1 และ CF = 1
· 4 บิตบนของเรจิสเตอร์ AL มีค่า 0
ตัวอย่าง
ก.
; AL = 0011 0111 = 37H ASCII 7
; BL = 0011 0100 = 34H ASCII 4
MOVAL,37H
MOVBL,34H
SUB AL,BL; (7-4)
AAS
; CL = 0000 0011 = unpacked BCD 03
ข.
; AL = 0011 0100 = 34H ASCII 4
; CL = 0011 0111 = 37H ASCII 7
MOVAL,34H
MOVCL,37H
SUB AL,CL; (4-7) = borrow 1 and result 14 – 7 = 7
; AL = 1111 1101, AF = 1, CF = 1
AAS
; AL = 0000 0111 = unpacked BCD 07
; CF = 1 borrow needed
DAS : Decimal Adjust for Subtraction
Operation. Corrects the result of subtracting two BCD (packed decimal) items in the AL. If the rightmost four bits have a value greater than 9 or the AF flag is 1, DAS subtracts 6 from the AL and sets the AF. If the leftmost four bits have a value greater than 9 or the CF flag is 1, DAS subtracts 60h from the AL and sets the CF.
Source Code. DAS
Object Code. 00101111
ใช้สำหรับการปรับค่าการลบเลข packed BCD เหมือนกับที่มีการปรับค่าของคำสั่ง DAA
คำสั่ง DAS มีวิธีการปรับค่า ดังนี้
· ถ้า 4 บิตล่างของเรจิสเตอร์ AL มีค่ามากกว่า 9 หรือ AF = 1 จะลบค่า 6 จากเรจิสเตอร์ AL และกำหนดให้ AF = 1
· ถ้า 4 บิตบนของเรจิสเตอร์ AL มีค่ามากกว่า 9 หรือ CF = 1 จะลบค่า 60h จากเรจิสเตอร์ AL และกำหนดให้ CF = 1
ตัวอย่าง
ก.
; AL = 1000 0110 = 86 packed BCD
; BH = 0101 0111 = 57 packed BCD
SUB AL,BH; AL =0010 1111 = 2FH
DAS
; subtract 0000 0110
; because 1111 in low nibbles > 9
; AL = 0010 1001 = 29 packed BCD
ข.
; AL = 0100 0101 = 45 packed BCD
; BH = 0110 0011 = 63 packed BCD
SUB AL,BH; AL = 1110 0010, CF = 1
DAS
; subtract 0110 0000
; because 1010 in upper nibbles > 9
; AL = 1000 0010 = 82 packed BCD, CF = 1
; CF = 1 means borrow was needed
DEC : Decrement by 1
Operation. Decrements 1 from a byte, or word in a register or memory, coded, for example, as DEC CX.
Source Code. DEC {register/memory}
Object Code. (two formats)
Register:|01001reg|
Reg/memory:|1111111w|mod001r/m|
NEG : Negate
Operation. Reverses a binary value from positive to negative and from negative to positive. NEG provides two’s complement of the specified operand: subtracts the operand from zero and adds 1. Operands may be a byte or word in a register or memory.
Note! มีผลกับค่า flags ดังนี้
· CF มีค่า 0 ถ้าผลลัพธ์เป็นบวก
มีค่า 1 ถ้าผลลัพธ์เป็นลบ
· PF มีค่า 0 ถ้าผลลัพธ์มีจำนวนบิตที่มีค่า 1 เป็นคี่
มีค่า 1 ถ้าผลลัพธ์มีจำนวนบิตที่มีค่า 1 เป็นคู่
· AF มีค่า 0 ถ้าผลการบวกเลขฐานสิบไม่ต้องปรับค่า
มีค่า 1 ถ้าผลการบวกเลขฐานสิบต้องปรับค่า
· ZF มีค่า 0 ถ้าผลลัพธ์ไม่ใช่ 0
มีค่า 1 ถ้าผลลัพธ์เป็น 0
· SFมีค่า 0 ถ้าผลลัพธ์มีค่าบวก
มีค่า 1 ถ้าผลลัพธ์มีค่าลบ
· OFมีค่า 1 ถ้าผลลัพธ์ใหญ่หรือเล็กกว่าที่จะเก็บได้ และมีค่าเป็น 0 ในกรณีอื่น
Source Code. NEG {register/memory}
Object Code. |1111011w|mod011r/m|
CMP : Compare
Operation. Compares the contents of two data fields. CMP internally subtracts operand 2 from operand 1 but does not change the values. Both operands are byte or word. CMP may compare register, memory, or immediate to a register or compare register or immediate to memory.
Source Code. CMP {register/memory},{register/memory/immediate}
Object Code. (three formats)
Reg/mem with reg:|001110dw|modregr/m|
Immed to accum’r:|0011110w|---data---|-data if w=1-|
Immed to reg/mem:|100000sw|mod111r/m|---data---|-data if sw = 00|
คำสั่ง CMP มีการทำงานคล้ายคำสั่ง SUB คือ CMP จะลบ source จาก destination แต่ไม่ได้เก็บค่าผลลัพธ์ ดังนั้นค่าใน source และ destination จึงไม่มีการเปลี่ยนแปลงจากการลบ ทำให้ได้ผลลับ flags ดังนี้
condition
OF SF ZF CF
Unsigned Operands
source < destination
xx00
source = destination
xx10
source > destination
xx01
Signed Operands
source < destination
0/100x
source = destination
001x
source > destination
0/110x
Note! x means don’t care 0 is clear 1 is set
5.2.3 Multiplication
MUL : Unsigned Multiplication
Operation. Multiplies an unsigned multiplicand by an unsigned multiplier. MUL treats a leftmost 1-bit as a data bit, not a negative sign. Here are the two operations:
MultiplicandMultiplier
(operand1)(operand 2)
ProductExample
8-bit AL
8-bit register/memoryAXMUL BL
16-bit AX
16-bit register/memoryDX:AXMUL BX
Source Code. MUL {register/memory}
Object Code. |1111011w|mod100r/m|
ใช้คูณเลขจำนวนเต็มไม่มีเครื่องหมาย สามารถคูณเลขขนาดไบต์และคำได้ มีรูปแบบการใช้ ดังนี้
MUL multiplier
โดยที่ multiplier เป็นได้ทั้งเรจิสเตอร์หรือหน่วยความจำ
สำหรับการคูณข้อมูลขนาดไบต์จะใช้ AL เป็น multiplicand และ แต่ถ้าเป็นการคูณข้อมูลขนาดคำจะใช้ AX เป็น multiplicand ผลลัพธ์จากการคูณ จะมีขนาดเป็นสองเท่า ถ้าเป็นการคูณข้อมูลขนาดไบต์ ผลลัพธ์จะมีขนาด 16 บิต เก็บอยู่ใน AX (หรือ AH:AL) ถ้า AH มีค่าเป็น 0 แฟลก CF และ OF จะมีค่าเป็น 0 มิฉะนั้นจะมีค่าเป็น 1 แต่ถ้าเป็นการคูณข้อมูลขนาดคำ ผลลัพธ์จะมีขนาด 32 บิต เก็บอยู่ใน DX:AX ถ้า DX มีค่าเป็น 0 แฟลก CF และ OF จะมีค่าเป็น 0 มิฉะนั้นจะมีค่าเป็น 1
การคูณข้อมูลขนาดคำ
AX
BX
CX
DX
AX
DXAX
*
SI
DI
BP
SP
word memory
การคูณข้อมูลขนาดไบต์
AH
AL
BH
BL
CH
CL
DH
DL
AL
AHAL
*
byte memory
ตัวอย่าง
moval,5
movbl,10
mulbl
; 5 * 10 , ax = 50
IMUL : Signed (Integer) Multiplication
Operation. Multiplies a signed multiplicand by a signed multiplier. IMUL treats a leftmost 1-bit as a negative sign. Here are the two operations:
MultiplicandMultiplier
(operand1)(operand 2)
ProductExample
8-bit AL
8-bit register/memoryAXIMUL BL
16-bit AX
16-bit register/memoryDX:AXIMUL BX
Source Code. IMUL {register/memory}
Object Code. |1111011w|mod101r/m|
เหมือน MUL แต่เป็นการคูณเลขจำนวนเต็มมีเครื่องหมาย และถ้าผลคูณไม่สามารถเก็บได้พอใน AL (กรณี 8 บิต) หรือ AX (ในกรณี 16 บิต) ค่าใน CF และ OF จะเป็น 1 มิฉะนั้น จะเป็น 0
AAM : ASCII Adjust for Multiplication
Operation. Corrects the product generated by multiplying two unpacked decimal values. AAM divides the AL by 10 and stores the quotient in the AH and the remainder in the AL.
Source Code. AAM
Object Code. |11010100|00001010|
คำสั่ง AAM จะเปลี่ยนค่าของผลลัพธ์ของการคูณเลขขนาดไบต์ เป็นค่า unpacked BCD 2 ค่า เก็บใน AH และ AL โดยที่ตัวตั้งและตัวคูณต้องเป็น unpacked BCD ด้วย
ในการปรับค่าผลลัพธ์ คำสั่ง AAM จะหารเรจิสเตอร์ AL ด้วย 10 และเก็บค่าส่วนใน AH ค่าเศษใน AL เช่น สมมุติว่า AL มีค่า 9 (00001001B) และ BL มีค่า 7 (0000111B) เมื่อใช้คำสั่ง MUL BL ผลลัพธ์ของการคูณ AL กับ BL ได้ผลลัพธ์ 00000000B เก็บใน AH และ 00111111B เก็บใน AL เมื่อใช้คำสั่ง AAM เรจิสเตอร์ AL จะถูกหารด้วย 10 แล้วเก็บส่วน คือ 00000110B ไว้ใน AH และเก็บเศษ คือ 00000011B ไว้ใน AL
ตัวอย่าง
; AL = 00000101
= unpacked BCD 5
; BH = 00001001
= unpacked BCD 9
mulbh;al * bh result in ax
;ax = 00000000 00101101 = 002dh
aam
;ax = 00000100 00000101
; = unpacked BCD 45
5.2.4 Division
DIV : Unsigned Division
Operation. Divides an unsigned dividend by an unsigned divisor. DIV treats a leftmost 1-bit as a data bit, not a minus sign. Here are the two types of division:
DividendDivisor
(operand1)(operand 2)
Quotient
RemainderExample
16-bit AX8-bit register/memoryAL
AH
DIV BH
32-bit DX:AX16-bit register/memoryAX
DX
DIV CX
Note! Division by zero causes a zero-divide interrupt.
Source Code. DIV {register/memory}
Object Code. |1111011w|mod110r/m|
กรณีที่ผลหาร (quotient) ไม่สามารถเก็บได้พอใน AL (กรณี 8 บิต) หรือ AX (กรณี 16 บิต) จะเกิด divide by zero interrupt
การหารจะคล้ายกับการคูณ แต่ทำกลับกัน ดังนี้
การหารข้อมูลขนาดคำ
AX
BX
CX
DX
DXAX
DXAX
/
เศษ จำนวนเต็ม
SI
DI
BP
SP
word memory
การหารข้อมูลขนาดไบต์
AH
AL
BH
BL
CH
CL
DH
DL
AX
AHAL
/
เศษ จำนวนเต็ม
byte memory
ตัวอย่าง
movax,13
movbl,5
divbl
; 13 / 5 , ah = 3, al = 2
ตัวอย่าง
; unsigned integer
; x = a/b
; y = a mod b
dosseg
.model small
.stack 1024
.data
x dw ?
y dw ?
a dw 7
b dw 3
.code
main proc
mov ax,@data
mov ds,ax
mov ax,a
mov dx,0 ; xor dx,dx
div b
mov x,ax ; x = 2
mov y,dx ; y = 1
mov ax,4c00h
int 21h
main endp
end main
IDIV : Signed (Integer) Division
Operation. Divides a signed dividend by a signed divisor. DIV treats a leftmost 1-bit as a negative sign. Here are the two types of division:
DividendDivisor
(operand1)(operand 2)
Quotient
RemainderExample
16-bit AX8-bit register/memoryAL
AH
IDIV BH
32-bit DX:AX16-bit register/memoryAX
DX
IDIV CX
Note! Division by zero causes a zero-divide interrupt.
Source Code. IDIV {register/memory}
Object Code. |1111011w|mod111r/m|
กรณีที่ผลหาร (quotient) ไม่สามารถเก็บได้พอใน AL (กรณี 8 บิต) หรือ AX (กรณี 16 บิต) จะเกิด divide by zero interrupt
เหมือน DIV แต่เป็นการหารเลขที่มีเครื่องหมาย
ตัวอย่าง
Dividend(AX)Divisor
Quotient (AL)Remainder(AH)
7
2
3
1
7
-2
-3
1
-7
2
-3
-1
-7
-2
3
-1
Note! The sign of the remainder is always the same as the dividend.
ตัวอย่าง
; signed integer
; x = a/b
; y = a mod b
dosseg
.model small
.stack 1024
.data
x dw ?
y dw ?
a dw -7
b dw 3
.code
main proc
mov ax,@data
mov ds,ax
mov ax,a
cwd
idiv b
mov x,ax ; x = -2 or 0FFFEh
mov y,dx ; y = -1 or 0FFFFh
mov ax,4c00h
int 21h
main endp
end main
ตัวอย่าง
; signed integer
; x = ((a+b)/d)*5
dosseg
.model small
.stack 1024
.data
x dw ?
a dw 120
b dw -20
d dw 4
.code
main proc
mov ax,@data
mov ds,ax
mov ax,a
add ax,b
cwd
idiv d
mov bx,5
imul bx
mov x,ax ; x = 125 or 7Dh
mov ax,4c00h
int 21h
main endp
end main
AAD : ASCII Adjust for Division
Operation. Corrects for division of ASCII values Use AAD before dividing into an unpacked decimal value in the AX (strip out ASCII 3s). AAD corrects the dividend to a binary value in the AL for a subsequent binary divide. It multiplies the AH by 10, adds the product to the AL, and clears the AH.
Source Code. AAD
Object Code. |11010101|00001010|
คำสั่ง AAD จะปรับค่าของตัวตั้งในการหารให้เป็นเลขฐานสอง ในเรจิสเตอร์ AL ซึ่งทำการโดยการคูณส่วนบนของตัวตั้งหรือค่าในเรจิสเตอร์ AH ด้วย 10 และบวกผลลัพธ์กับส่วนล่างของตัวตั้งหรือค่าในเรจิสเตอร์ AL และจะทำให้ค่าใน AH เป็น 0 คำสั่ง AAD จะต้องถูกเรียกใช้ก่อนการหาร
ตัวอย่าง
; AX = 0000 0011 0000 0111 unpacked BCD for 37 decimal
; CL = 0000 0101 unpacked BCD for 5 decimal
aad
; adjust to binary before division
; ax = 0025h = 37
divcl; divide ax by cl
; al = quotient = 07 unpacked BCD
; ah = remainder = 02 unpacked BCD
5.2.5 Sign-Extension
CBW : Convert Byte to Word
Operation. Extends a one-byte signed value in the AL to a word by duplicating the sign (bit 7) of the AL through the bits in the AH.
Source Code. CBW
Object Code. 10011000
คำสั่ง CBW เป็นคำสั่งที่ลอกค่าของบิต 7 ในเรจิสเตอร์ AL ไปใส่ในเรจิสเตอร์ AH
7 0
7 0
AH
AL
ปกติใช้เพื่อเปลี่ยนข้อมูลที่มีเครื่องหมายขนาดไบต์ให้เป็นขนาดคำ ก่อนการบวกหรือลบ
CWD : Convert Word to Doubleword
Operation. Extends a one-word signed value in the AX to a doubleword by duplicating the sign (bit 15) of the AX through the DX, typically to generate a 32-bit dividend.
Source Code. CWD
Object Code. 10011001
คำสั่ง CWD เป็นคำสั่งที่ลอกค่าของบิต 15 ในเรจิสเตอร์ AX ไปใส่ในเรจิสเตอร์ DX
15 0
15 0
DX
AX
ปกติใช้เพื่อเปลี่ยนข้อมูลที่มีเครื่องหมายขนาดคำให้เป็นขนาดสองคำ ก่อนการหาร
สรุป คำสั่งที่เกี่ยวข้องกับการบวกลบคูณหาร
integer
binary
decimal
signed
unsignedASCIIUnpacked BCDPacked BCD
addition
add des,srcเหมือน signedaaaaaa
daa
or al,30h
adc des,srcเหมือน signed
inc desเหมือน signed
subtraction
sub des,srcเหมือน signedaasaas
das
or al,30h
sbb des,srcเหมือน signed
dec desเหมือน signed
neg des
cmp des,srcเหมือน signed
multiplication
imul src
mul src
aam
division
cbw
cwd
aad
idiv src
div src
หมายเหตุ การบวกลบคูณหาร (ASCII, Unpacked BCD) และ Packed BCD
อย่าลืม ว่าทำได้ทีละไบต์ และ destination ต้องเป็น AL เท่านั้น ข้อมูลที่จะต้องนำมากระทำการต้องเก็บเป็นตัวเลขที่ถูกต้อง เช่น ASCII 5 และ Unpacked BCD 5 ต้องเก็บเป็น 35H และ 05H ตามลำดับ เป็นต้น หรือ Packed BCD
5 และ 24 ต้องเก็บเป็น 05H และ 24H เป็นต้น เลขเหล่านี้จะต้องอยู่ในช่วง 0 ถึง 9 จึงจะถูกต้อง
การบวก
. ASCII หรือ Unpacked BCD
· ใส่ ASCII หรือ Unpacked BCD ใน AL
· ใช้คำสั่ง add (หรือ adc ถ้าต้องการนำ CF มาบวกด้วย) โดยมี AL เป็น destination และ ASCII หรือ Unpacked BCD ที่ต้องการนำมาบวกเป็น source
· ใช้คำสั่ง aaa เพื่อปรับค่าให้ถูกต้อง และจะกำหนดให้ 4 บิตบนของ AL เป็น 0 เสมอ ถ้ามีการทดจะกำหนดให้ AF และ CF มีค่าเป็น 1 และบวก AH ด้วย 1
· คำตอบจะเป็น Unpacked BCD ที่ต้องการ เพราะคำสั่ง aaa จะปรับค่าให้ 4 บิตบนของ AL เป็น 0 เสมอ ถ้าต้องการคำตอบในรูป ASCII ให้ใช้คำสั่ง or al,30h อีกคำสั่งหนึ่ง ถ้าต้องการดูว่ามีการทดหรือไม่ให้ดูที่ CF หรือ AF
ต.ย.
1) กรณีไม่มีการทด เช่น 35h+34h
ASCII
binary
mov al,35h
AL35h
0011 0101AH = ?
mov bh,34h
BH34h
0011 0100
add al,bh
AL69h
0110 1001
AF = 0
aaa
AL09h
0000 1001AH = ?
2) กรณีมีการทด เช่น 39h+39h
ASCII
binary
mov al,39h
AL39h
0011 1001AH = ?
mov bh,39h
BH39h
0011 1001
add al,bh
AL72h
0111 0010
AF = 1
; note 0010 + 0110 = 1000
aaa
AL08h
0000 1000AH = ? + 1 AF =1 CF = 1
. Packed BCD
· ใส่ Packed BCD ใน AL
· ใช้คำสั่ง add (หรือ adc ถ้าต้องการนำ CF มาบวกด้วย) โดยมี AL เป็น destination และ Packed BCD ที่ต้องการนำมาบวกเป็น source
· ใช้คำสั่ง daa เพื่อปรับค่าให้ถูกต้อง ถ้ามีการทดใน 4 บิตล่าง AF = 1 และถ้ามีการทดใน 4 บิตบน CF = 1
· คำตอบจะเป็น Packed BCD ที่ต้องการ ถ้าจะตรวจสอบว่ามีการทดหรือไม่ให้ดูที่ CF
ต.ย.
1) กรณีไม่มีการทด เช่น 15h+24h
ASCII
binary
mov al,15h
AL15h
0001 0101
mov bh,24h
BH24h
0010 0100
add al,bh
AL39h
0011 1001
CF = 0 AF = 0
daa
AL39h
0011 1001
2) กรณีมีการทด เช่น 93h+16h
ASCII
binary
mov al,93h
AL93h
1001 0011
mov bh,16h
BH16h
0001 0110
add al,bh
ALa9h
1010 1001
CF = 0 AF = 0
; note 1010 + 0110 = 0000
daa
AL09h
0000 1001AF =0 CF = 1
การลบ
. ASCII หรือ Unpacked BCD
· ใส่ ASCII หรือ Unpacked BCD ใน AL
· ใช้คำสั่ง sub (หรือ sbb ถ้าต้องการนำ CF มาลบด้วย) โดยมี AL เป็น destination และ ASCII หรือ Unpacked BCD ที่ต้องการนำมาลบเป็น source
· ใช้คำสั่ง aas เพื่อปรับค่าให้ถูกต้อง และจะกำหนดให้ 4 บิตบนของ AL เป็น 0 เสมอ ถ้ามีการยืมจะกำหนดให้ AF และ CF มีค่าเป็น 1 และลบ AH ด้วย 1
· คำตอบจะเป็น Unpacked BCD ที่ต้องการ เพราะคำสั่ง aas จะปรับค่าให้ 4 บิตบนของ AL เป็น 0 เสมอ ถ้าต้องการคำตอบในรูป ASCII ให้ใช้คำสั่ง or al,30h อีกคำสั่งหนึ่ง ถ้าต้องการดูว่ามีการยืมหรือไม่ให้ดูที่ CF หรือ AF
ต.ย.
1) กรณีไม่มีการยืม เช่น 35h-34h
ASCII
binary
mov al,35h
AL35h
0011 0101AH = ?
mov bh,34h
BH34h
0011 0100
sub al,bh
AL01h
0000 0001
AF = 0
aas
AL01h
0000 0001AH = ?
2) กรณีมีการทด เช่น 38h-39h
ASCII
binary
mov al,38h
AL38h
0011 1000AH = ?
mov bh,39h
BH39h
0011 1001
sub al,bh
ALffh
1111 1111
AF = 1
; note 1111 - 0110 = 1001
aas
AL09h
0000 1001AH = ? - 1 AF =1 CF = 1
. Packed BCD
· ใส่ Packed BCD ใน AL
· ใส่ Packed BCD ในเรจิสเตอร์หรือหน่วยความจำที่ต้องการนำมาลบ
· ใช้คำสั่ง sub (หรือ sbb ถ้าต้องการนำ CF มาลบด้วย) โดยมี AL เป็น destination และ Packed BCD ที่ต้องการนำมาลบเป็น source
· ใช้คำสั่ง das เพื่อปรับค่าให้ถูกต้อง ถ้ามีการยืมใน 4 บิตล่าง AF = 1 และถ้ามีการยืมใน 4 บิตบน CF = 1
· คำตอบจะเป็น Packed BCD ที่ต้องการ ถ้าจะตรวจสอบว่ามีการยืมหรือไม่ให้ดูที่ CF
ต.ย.
1) กรณีไม่มีการยืม เช่น 25h-14h
ASCII
binary
mov al,25h
AL25h
0010 0101
mov bh,14h
BH14h
0001 0100
sub al,bh
AL11h
0001 0001
CF = 0 AF = 0
das
AL11h
0001 0001
2) กรณีมีการยืม เช่น 16h-93h
ASCII
binary
mov al,16h
AL16h
0001 0110
mov bh,93h
BH93h
1001 0011
sub al,bh
ALa9h
1000 0011
CF = 1 AF = 0
; note 1000 – 0110 = 0010
das
AL23h
0010 0011;AF =0 CF = 1
การคูณ
มีเฉพาะ Unpacked BCD เท่านั้น
1. ใส่ตัวตั้งซึ่งเป็น Unpacked BCD ใน AL
2. ใช้คำสั่ง mul โดยมี Unpacked BCD อีกตัวหนึ่งเป็นตัวคูณ
3. ใช้คำสั่ง aam เพื่อปรับค่าผลลัพธ์ที่เก็บใน AX ให้เป็น Unpacked BCD สองตัวเก็บใน AH และ AL ตามลำดับ
ต.ย.
UnpackedBinary
moval,5 AL 05 0000 0101
movbl,9
BL 09 0000 1001
mulbl
AX 002d 0000 0000 0010 1101
aam
AX 0405 0000 0100 0000 0101
หมายเหตุ aam หาร AL ด้วย 10 เก็บผลลัพธ์ใน AH และเศษใน AL
การหาร
มีเฉพาะ Unpacked BCD เท่านั้น
1. ใส่ตัวตั้งซึ่งเป็น Unpacked BCD ใน AX
2. ใช้คำสั่ง aad เพื่อปรับค่าจาก Unpacked BCD เป็น binary คำสั่งนี้จะคูณ AH ด้วย 10 แล้วบวกกับ AL
3. ใช้คำสั่ง div โดยมี Unpacked BCD อีกตัวหนึ่งเป็นตัวหาร จะได้ผลลัพธ์เก็บใน AL และเศษเก็บใน AH
ต.ย.
UnpackedBinary
movax,0307h AX 03 07 0000 0011 0000 0111
aad
AX 0025 0000 0000 0010 0101
movcl,5
CL 05 0000 0101
divcl
AX 0207 0000 0010 0000 0111
Computer Science, Prince of Songkhla University