问题: 设有两个8位BIT的数A=a7a6a5a4a3a2a1a0, B=b7b6b5b4b3b2b1b0.进位标志CF, 溢出标志OF.则:
计算C=A+B时,OF=? CF=? 计算C=A-B时, OF=? CF=?
网上找了半天,总说什么有符号数,无符号数,看晕了.二进制形式的一个数,你怎么知道它是有符号的还是无符号的?只好写程序试验了.程序是将0到255之间任意两个数相加,将产生溢出或者进位的数找出来.
通过对结果的分析,得出以下溢出和进位的确定方式:
- .section .data
- flow:
- .asciz "%3d + %3d = %3d/tOverflow/n"
- carry:
- .asciz "%3d + %3d = %3d/tCarry/n"
- both_no:
- .asciz "%3d + %3d = %3d/tNone occured./n"
- both:
- .asciz "%3d + %3d = %3d/tBoth occured./n"
- .section .text
- .globl _start
- _start:
- movl $0, %ecx
- movl $0, %edx
- begin:
- movb %cl, %al
- movb %dl, %bl
- addb %bl, %al
- jc has_carry
- jo has_flow
- jmp loop_inc
- pushl %ecx
- pushl %edx
- movzx %al, %ebx
- pushl %ebx
- movzx %dl, %ebx
- pushl %ebx
- movzx %cl, %ebx
- pushl %ebx
- push $both_no
- call printf
- addl $16, %esp
- popl %edx
- popl %ecx
- loop_inc:
- incb %dl
- cmpb $0, %dl
- jnz loop_end
- incb %cl
- cmpb $0, %cl
- jz end
- movb %cl, %dl
- loop_end:
- jmp begin
- has_carry:
- jo has_both
- pushl %ecx
- pushl %edx
- movzx %al, %ebx
- pushl %ebx
- movzx %dl, %ebx
- pushl %ebx
- movzx %cl, %ebx
- pushl %ebx
- push $carry
- call printf
- addl $16, %esp
- popl %edx
- popl %ecx
- jmp loop_inc
- has_flow:
- pushl %ecx
- pushl %edx
- movzx %al, %ebx
- pushl %ebx
- movzx %dl, %ebx
- pushl %ebx
- movzx %cl, %ebx
- pushl %ebx
- push $flow
- call printf
- addl $16, %esp
- popl %edx
- popl %ecx
- jmp loop_inc
- has_both:
- pushl %ecx
- pushl %edx
- movzx %al, %ebx
- pushl %ebx
- movzx %dl, %ebx
- pushl %ebx
- movzx %cl, %ebx
- pushl %ebx
- push $both
- call printf
- addl $16, %esp
- popl %edx
- popl %ecx
- jmp loop_inc
- end:
- movl $1, %eax
- movl $0, %ebx
- int $0x80
- 不管你把数据视为无符号还是有符号,计算时自动把最高位视为符号位.当两个符号位相同的数做加法时,如果结果的符号位发生变化,则为溢出.
- 当两个符号位不同的数做减法时,以A-B=C为例,如果A与C的符号位不同则为溢出.
- 其它情况下均不会有溢出.
- 关于进位:
- 当两个数相加的结果的长度增大时会产生进位.
- 如果将数看作无符号的(不管机器如何看待它们),小数减大数一定发生进位,即"借位"也被视为进位,英文叫"CARRY".大数减小数永远不会产生进位.
- 两个N位的数相加的结果大于2N - 1时发生进位.否则不发生进位.