PDA

View Full Version : در تفریق دو عدد، کی سرریز اتفاق می افته؟



Developer Programmer
سه شنبه 17 بهمن 1385, 20:49 عصر
سلام
اگه دو عدد زیر رو تفریق کنیم آیا سرریز اتفاق می افته یا نه؟ (فرض کنید که جواب هم باید در 6 رقم بگنجد)

اعداد در مبنای 10 هستن ، علامتدار و به روش مکمل 10 حساب میشن


<<Signed numbers>>
072532-03250

american_iran2006
سه شنبه 17 بهمن 1385, 22:47 عصر
من فکر نمی کنم تو شش بیت سرریز اتفاق بیفته و مخصوصا که اصلا کسر کردن سر ریز نداره

اما جمع :

تو هفت بیت هست که اعداد علامت دار این مشکل رو دارن و کار به بیت نقلی کشیده

میشه

Developer Programmer
سه شنبه 17 بهمن 1385, 23:25 عصر
مرسی از وقتی که واسه مشکل من صرف کردید

من فکر نمی کنم تو شش بیت سرریز اتفاق بیفته
من شش رقم منظورم بود، نه شش بیت

اصلا کسر کردن سر ریز نداره
واسه تفریق هم باید جمع کرد

کلا مشکلم اینجا بود که من محاسبات رو در مبنای 10 انجام میدادم و چون یک رقم نقلی داشتم که روی بیت علامت تاثیر می ذاشت، فکر میکردم سرریز رخ داده... با کلی کتاب و جستجو فهمیدم که فقط باید در مبنای دو محاسبه کرد.

Best Programmer
چهارشنبه 18 بهمن 1385, 23:11 عصر
سلام و ببخشید که دیر در بحث وارد شدم . اصلا وقت نمی کردم. خودت دیگه میدونی که وقت بیکار من از کی شروع میشه
افشین خان . اگر هنوز مشکلی داری من بخشی از متن کتاب را میزارم برای مطالعه :


Subtraction
Now that you have integer addition under your belt, integer subtraction should be a breeze. The following
sections describe the ins and outs of integer subtraction in assembly language.
The SUB instruction
The basic form for subtraction is the SUB instruction. Just like the ADD instruction, it can be used to subtract
both unsigned and signed integers. The format of the SUB instruction is
sub source, destination
where the source value is subtracted from the destination value, with the result stored in the
destination operand location. The source and destination operands can be 8-, 16-, or 32-bit registers
210
Chapter 8
or values stored in memory (but again, they cannot both be memory locations at the same time). The
source value can also be an immediate data value.
As with the ADD instruction, the GNU assembler requires a size character to be added to the mnemonic.
The usual characters apply (b for byte, w for word, and l for doubleword).
The subtest.s program demonstrates using the SUB instruction in an assembly language program:
# subtest1.s - An example of the SUB instruction
.section .data
data:
.int 40
.section .text
.globl _start
_start:
nop
movl $0, %eax
movl $0, %ebx
movl $0, %ecx
movb $20, %al
subb $10, %al
movsx %al, %eax
movw $100, %cx
subw %cx, %bx
movsx %bx, %ebx
movl $100, %edx
subl %eax, %edx
subl data, %eax
subl %eax, data
movl $1, %eax
movl $0, %ebx
int $0x80
The subtest1.s program performs various basic subtractions using immediate values, registers, and
memory locations. After assembling the program, you can watch the registers and memory location in
the debugger as it is running. Note the values as the SUB instructions are executed. Note particularly the
last SUB instruction, which subtracts the value in the EAX register (-30) from the value at the data1
memory location (40):
(gdb) print $eax
$1 = -30
(gdb) x/d &data
0x80490ac <data>: 40
(gdb) s
_start () at subtest1.s:23
23 movl $1, %eax
(gdb) x/d &data
0x80490ac <data>: 70
(gdb)
The processor subtracted -30 from 40, and got the correct answer, 70.
211
Basic Math Functions
It is extremely important to remember the order of the SUB instruction for the GNU assembler. Using
the Intel syntax will produce the wrong results!
A close relative of the SUB instruction is the NEG instruction. It produces the two’s complement of a
value. This is the same as using the SUB instruction to subtract the value from zero, but quicker.
Carry and overflow with subtraction
Similar to the ADD instruction, the SUB instruction modifies several of the EFLAGS register bits after it performs
the subtraction operation. However, the concept of carry and overflow are different in subtraction.
In addition, the carry flag is set when the addition result is too large of a positive value for the data size
used to hold the operands. Obviously, with subtraction, the problem arises when the subtraction result
becomes too large of a negative value for the data size.
For example, with unsigned integers, what happens when you subtract 5 from 2? The subtest2.s program
demonstrates this problem:
# subtest2.s - An example of a subtraction carry
.section .text
.globl _start
_start:
nop
movl $5, %eax
movl $2, %ebx
subl %eax, %ebx
jc under
movl $1, %eax
int $0x80
under:
movl $1, %eax
movl $0, %ebx
int $0x80
The subtest2.s program simply places the 5 value in the EAX register, and the 2 value in the EBX register,
and then subtracts the EAX register from the EBX register. The JC instruction is used to jump if the
carry flag is set. The result code from the program will be either the subtraction value or a 0 if the carry
flag is set.
After assembling the program, run it and see what happens:
$ ./subtest2
$ echo $?
0
$
The carry flag was set when the result was less than zero (which is invalid in unsigned integers).
However, by examining the value of the EBX register in the debugger, you should see something
interesting:
(gdb) print $ebx
$1 = -3
(gdb)
212
Chapter 8
The EBX register contained the correct value, even though it was “supposed” to be unsigned. The processor
does not know if you are using unsigned or signed integers. It is up to your program to determine
when a value is outside of the range of the unsigned (or signed) values.
The carry flag is used to determine when subtracting unsigned integers produces a negative result.
As with adding signed integers, if you are subtracting signed integers, the carry flag is not useful, as the
result can often be negative. Instead, you must rely on the overflow flag to tell you when you have
reached the data size limits. This is demonstrated in the subtest3.s program:
# subtest3.s - An example of an overflow condition in a SUB instruction
.section .data
output:
.asciz “The result is %d\n”
.section .text
.globl _start
_start:
movl $-1590876934, %ebx
movl $1259230143, %eax
subl %eax, %ebx
jo over
pushl %ebx
pushl $output
call printf
add $8, %esp
pushl $0
call exit
over:
pushl $0
pushl $output
call printf
add $8, %esp
pushl $0
call exit
The subtest3.s program demonstrates subtracting a positive value stored in the EAX register from
a negative value stored in the EBX register, producing a value too large for the 32-bit EBX register. The
JO instruction is used to detect the overflow flag, and send the program to the over: label, setting the
output value to 0. After assembling the program and linking it with the C libraries, you can run it to
see the output:
$ ./subtest3
The result is 0
$
The overflow condition was detected and the JO instruction was executed and followed. You can test to
determine whether the opposite condition works by changing the value assigned to the EAX to a negative
value:
movl $-1259230143, %eax
213
Basic Math Functions
and running the program again:
$ ./subtest3
The result is -331646791
$
This time, subtracting a negative number produced a smaller negative number, well within the data size
limits, and not setting the overflow flag.

منبع : Wrox.Professional.Assembly.Language
ص : 210 - 214 | توضیح : AT&T syntax
و از این که حال و حوصله کلی تایپ را هم ندارم ببخشید . دیگه خودت یه پا استادی دیگه.