เว็บไซต์บุคลากรภาควิชา...

42
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 unsigned signed binary decimal decimal OF CF 11111001 249 -7 + 00000010 2 +2 11111011 251 -5 0 0 b) arithmetic carry unsigned signed binary decimal decimal OF CF 11111100 252 -4 + 00000101 5 +5 (1)00000001 1 +1 0 1 (invalid) (valid) c) overflow Computer Science, Prince of Songkhla University 1

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