110 likes | 237 Views
CS344-321 Assembly Language Programming. Period 22. Arithmetic Instructions add บวกได้ทั้งเลข binary ที่มีเครื่องหมายและไม่มีเครื่องหมาย
E N D
CS344-321 Assembly Language Programming Period 22
Arithmetic Instructions add บวกได้ทั้งเลข binary ที่มีเครื่องหมายและไม่มีเครื่องหมาย การตรวจสอบว่า เลขที่ไม่มีเครื่องหมาย ผลลัพธ์ อยู่นอกช่วงหรือไม่ ตรวจที่ CF ถ้าเป็น 1 แสดงว่าคำตอบผิด เพราะไม่สามารถเก็บได้ ส่วนเลขมีเครื่องหมายให้ตรวจที่ OF โดย คอมพิวเตอร์จะตรวจสอบว่าค่าที่นำมาบวกมีเครื่องหมายเหมือนกัน แล้วให้ผลลัพธ์ที่มี เครื่องหมายต่างจากของเดิม แสดงว่า ค่าอยู่นอกช่วง (ข้อดีของ two complement) adc เป็นการนำ CF มาบวกด้วย เช่น ในกรณีที่ต้องการบวกเลข 32 บิต โดยบวกทีละ 16 บิต inc บวก 1 ที่ operand
ตัวอย่างการบวกเลข 32 bits .data opd1 dw 0FE03h, 0AB12h opd2 dw 0CA25h, 0FFEDh result dd ? .code mov ax,@data mov ds,ax
mov ax,opd1 opd1+3 opd1+2 opd1+1 opd1 add ax,opd2 mov result,ax opd2+3 opd2+2 opd2+1 opd2 mov ax,opd1+2 adc ax,opd2+2 result+3 result+2 result+1 result mov result+2,ax การดูว่าคำตอบเก็บได้พอหรือไม่ดูที่ CF เพราะเป็นการบวกเลขไม่มีเครื่องหมาย AB 12 FE 03 FF ED CA 25 CF
sub ลบได้ทั้งเลข binary ที่มีเครื่องหมายและไม่มีเครื่องหมาย การตรวจสอบว่า เลขที่ไม่มีเครื่องหมาย ผลลัพธ์ อยู่นอกช่วงหรือไม่ ตรวจที่ CF ถ้าเป็น 1 แสดงว่าคำตอบผิด เพราะไม่สามารถเก็บได้ ส่วนเลขมีเครื่องหมายให้ตรวจที่ OF sbb เป็นการนำ CF มาลบด้วย เช่น ในกรณีที่ต้องการลบเลข 32 บิต โดยลบทีละ 16 บิต dec ลบ 1 ที่ operand
neg เป็นการเปลี่ยนเครื่องหมายของ operand หรือ ทำ two complement กับ operand หรือ เท่ากับ 0 - operand ระวัง!neg immediate ไม่ได้ เช่น neg 12 ผิด และ mov ax,-32768 neg ax จะทำใหเเกิด overflow cmp เหมือนลบ แต่ destination ไม่เปลี่ยนค่า จะทำให้ flags ต่างๆ เปลี่ยนซึ่งจะมีผลกับคำสั่ง กระโดด ที่จะกล่าวในภายหลัง
mul สำหรับการคูณเลข binary ไม่มีเครื่องหมาย ข้อมูลขนาด 8 บิต ต้องใช้ al เป็นตัวตั้งเสมอ ผลลัพธ์จะเก็บใน ax และ ข้อมูลขนาด 16 บิต ต้องใช้ ax เป็นตัวตั้งเสมอ ผลลัพธ์จะเก็บใน dx และ ax ผลลัพธ์อยู่นอกช่วงหรือไม่ดูที่ CF หรือ OF imul สำหรับการคูณเลข binary มีเครื่องหมาย เหมือน mul แต่ผลลัพธ์อยู่นอกช่วงหรือไม่ดูที่ CF หรือ OF ระวัง! ใช้ immediate เป็น operand หรือตัวคูณไม่ได้ เช่น mul 10 ผิด
div สำหรับการหารเลข binary ไม่มีเครื่องหมาย ข้อมูลขนาด 8 บิต ต้องใช้ ax เป็นตัวตั้งเสมอ ผลลัพธ์จะเก็บใน al เศษเก็บใน ah และ ข้อมูลขนาด 16 บิต ต้องใช้ dx และ ax เป็นตัวตั้งเสมอ ผลลัพธ์จะเก็บใน ax และ เศษเก็บใน dx ผลลัพธ์ (quotient) อยู่นอกช่วงจะเกิด divide by zero interrupt idiv สำหรับการหารเลข binary มีเครื่องหมาย เหมือน div สำหรับเศษจะมีเครื่องหมายตามตัวตั้ง ผลลัพธ์ (quotient) อยู่นอกช่วงจะเกิด divide by zero interrupt ระวัง! ใช้ immediate เป็น operand หรือตัวหารไม่ได้ เช่น div 10 ผิด
ในกรณีที่ต้องการขยายขนาดของข้อมูลโดยที่ค่าของข้อมูลยังคงเหมือนเดิมในกรณีที่ต้องการขยายขนาดของข้อมูลโดยที่ค่าของข้อมูลยังคงเหมือนเดิม ก) แบบ two complement ทำดังนี้ copy sign bit เช่น เดิม 8 บิตมีค่า 01001100 ใหม่ 16 บิตให้ค่าเท่าเดิม คือ 00000000 01001100 เดิม 8 บิตมีค่า 11001100 ใหม่ 16 บิตให้ค่าเท่าเดิม คือ 11111111 11001100 สำหรับ intel 8080/8088 ใช้คำสั่ง cbw เมื่อต้องการขยายจาก 8 บิตใน al เป็น 16 บิตใน ax ใช้คำสั่ง cwd เมื่อต้องการขยายจาก 16 บิตใน ax เป็น 32 บิตใน dx และ ax ข) แบบ signed magnitude เลื่อน sign บิตไปอยู่ซ้ายสุดที่ signed บิตใหม่ แล้วเปลี่ย signed บิตเดิมให้เป็ย 0 เช่น เดิม 8 บิตมีค่า 01001100 ใหม่ 16 บิตให้ค่าเท่าเดิม คือ 00000000 01001100 เดิม 8 บิตมีค่า 11001100 ใหม่ 16 บิตให้ค่าเท่าเดิม คือ 10000000 01001100
ตัวอย่าง (x*y/z)/2 เมื่อเป็นเลขจำนวนเต็มมีเครื่องหมาย และเศษจะถูกตัดทิ้ง .data x dw 4 y dw 5 z dw 3 .code mov ax,@data mov ds,ax
mov ax,x ; multiplicand in ax imul y ; multiplier in y, result in dx:ax idiv z ; dividend in dx:ax, result in ax remainder in dx cwd ;copy sign bit in ax to dx so dividend in dx:ax has ;the same value as in ax , remainder in dx is lost ;if you want remainder in dx , please copy to temporary mov cx,2 idiv cx ;diveder in cx = 2 result in ax remainder in dx