The distinction between signed and unsigned numbers in the assembly and CF,OF flag bits

Source: Internet
Author: User
Tags numeric mul numeric value strlen truncated
The distinction between signed and unsigned numbers in the assembly and CF,OF flag bits first, there is only one standard.

First of all need to know that the computer to the value of the storage of a complementary form of storage, one avoids the embarrassment of +0 and 0, and the addition and subtraction of the number can be unified to complement the addition.
At the level of assembly language, when defining variables, there is no signed and Unsignde, and the assembler all treats the integer literal you enter as a signed number (the highest bit of the symbol is determined according to the input numeric symbol) and is processed into a binary complement to the computer, only this one standard.
The assembler does not differentiate between signed and unsigned and is treated with two criteria, which are all considered symbolic. And they are all compiled into a complement. That is, the db-20 is compiled after: EC, and DB 236 is also an EC after compilation. Here's a little problem, thinking deep friends will find that the DB is allocated a byte, then a word energy-saving representation of the signed integer range is:-128 ~ +127, then the DB 236 exceeds this range, how can. Yes, +236 of the complement is indeed beyond the scope of a byte, then take two bytes (of course more bytes better) can be installed, should be: XX EC, that is, +236 of the complement should be XX EC, a byte can not fit, but, do not forget the concept of "truncation", That is, the final result is truncated, the EC is two bytes, truncated to EC, so this is a "beautiful mistake", why so say. Because, when you think of 236 as an unsigned number, it compiles the result is also the EC, this is happy, although the assembler only with a standard to deal with, but borrowed "truncation" This beautiful error, the result is met two standard. That is, give you a byte, you want to enter a signed number, such as 20 then the result of the assembly is correct, if you enter 236 then you must be treated as an unsigned number (because 236 is not in a word energy-saving representation of the signed number of the range AH), the result is also correct. So give everyone an illusion: the assembler has two sets of standards, will distinguish between signed and unsigned, and then separately compiled. In fact, you have been cheated. :-) second, there are two sets of directives.

The 1th note Assembler uses only one method to assemble the entire number of digital polygons into a true number of machines. But not that the computer does not differentiate between signed and unsigned numbers, instead, the computer is very clear about the number of signed and unsigned numbers, because there are two sets of instructions for the computer to handle some of the same functions as a fallback, which is to be prepared for both signed and unsigned numbers, respectively. But here's one thing to emphasize, whether a number is a signed number or an unsigned number, the computer does not know, it is up to you to decide, when you think you want to deal with the number is signed, then you use the set of signed instructions, when you think you want to deal with the number is unsigned, then use to deal with the unsigned number of the set of instructions , the computer only calculates each one according to the instruction, and does not care whether the binary data is signed or unsigned, which relies on the programmer to determine whether the numeric value is signed or unsigned, and that's it.
Add and subtract has only one set of instructions, because this set of instructions applies to both signed and unsigned (the complement of what has just been said). And some instructions, such as: Mul div movzx ... is to handle unsigned numbers, and these: Imul idiv movsx ... is to handle signed (i.e. to provide two sets of instructions for signed and unsigned)
For example:
In the assembly, we put two data into memory, one byte x is: 0x EC, one byte y is: 0x 02.
found no negative sign, are positive, ok so the highest position of the negative sign is set to 0, and then the X truncation processing, to get
X:
1 1 1 0 1 1 0 0
Y:
0 0 0 0 0 0 1 0

Note here that x, if X is a signed number, although we give an EC positive, but because of truncation processing, the highest bit is 1, a negative number, and because this is a complement to save, the original code is still 2 -20,y
When viewed as an unsigned number, the first bit of the sign bit does not look, x = 236, y = 2.
But from the computer point of view, this is a string of binary, which has what signed unsigned numbers
The following with the add command to do the addition operation, the computer began to work, it just need to add each bit, only this, it is not divided into what is signed, unsigned.
Results:
1 1 1 0 1 1 1 0

This result is treated as a signed number:-18, the unsigned number is 238. Again, the computer thinks that this is still a string of binaries, so the add command can be used for both signed and unsigned situations. (hehe, in fact why should complement Ah, is for this chant,:-))
Multiplication is not necessary, you must use two sets of instructions, signed case with the result of using Imul: 0x FF D8 is-40. Unsigned case with Mul, get: 0x D8 is 472. Iii. of, CF, SF Mark

Why say three marks, because I am unsigned in the assembly, the sign of doubt is from the learning of these three markers to produce.
First look at the CF Mark Bit, the book said CF Mark Bit only for the unsigned number of meaningful, first understand that even if the two signed number added, it will also lead to CF changes, not to say the number of symbols, the compiler does not set the CF bit.
Since the change of the CF's Mark bit is due to the highest significant bit (if for 8 digits, which is the 8th digit) to the higher (9th bit) to produce a carry or borrow, and for the signed number, the highest bit is the sign bit, its change and the value bit change meaning is different. Therefore, for the signed number, CF may also change, but its change is meaningless. If the number is unsigned, its change means that 8 bits of memory or register are not enough to hold the data because the data generates a carry or borrow.
Look again at the mark bit, it is only meaningful to the signed number, because two standard 8-bit signed data (the standard refers to the assignment of the time not to assign more than the number of signed numbers, due to truncation, that is, 8 bits can be saved, the data stored in the numerical value has long been changed), These 2 data are only added to the same number (both positive and negative) to overflow, that is, the result exceeds the range of signed numbers. For example, 2 positive numbers, the sign bit (8th bit) is 0, the addition occurs after overflow, the sign bit because the 7th digit of the carry becomes 1, two positive numbers are added to a negative number. This has a effect on the of, so that the role of is due to the change of the sign bit, if it is two unsigned number, the highest bit is not symbolic meaning, the change is meaningless, so that is only for the number of symbols have meaning.
The last SF logo, with the above introduction, can understand SF is the highest bit of the symbolic bit meaning, for the unsigned number, the highest bit represents the numerical significance, not symbolic meaning. four, lovely and scary C language.

Why did you pull the C again? Since most of the friends who encounter signs or unsigned problems are caused by the signed and unsigned statements in C, why do they start from the assembly? Because we now use the C compiler, regardless of GCC or VC6 cl, is the C language code compiled into assembly language code, and then assembler into machine code. Figuring out the assembly is tantamount to fundamentally understanding C, and, using machine thinking to think about problems, you have to use a compilation. (I usually have some strange C-language problems to compile it into a compilation.) )

C is lovely, because C in line with the kiss principle, the abstraction of the machine is just good, let us improve the thinking level (more humane than the assembly machine level), and not too far away from the machine (like C #, Java and so on too far). Originally K&r version of C is a high-level assembly ...:-)

C is scary because it reacts to everything at the machine level, like this one with no sign (Java does not have this problem because it is designed to have all integers signed). In order to illustrate the dreadful special example of C:

#include <stdio.h> 
#include <string.h> 

int main ()
{
int x = 2; 
char * str = "ABCD"; 
int y = (X-strlen (str))/2;
Note: As the original author writes, the compiler might optimize it by using the right shift instruction instead of the division instruction, changing to 3 to see
printf ("%d\n", y);
}

The result should be-1 but get: 2147483647. Why? Because the return value of strlen, the type is size_t, that is, unsigned int, when mixed with int, the int type is automatically converted to unsigned int, and the result is naturally unexpected ...
Observing the compiled code, the division instruction is a Div, which means unsigned division. The workaround is to cast the conversion to int y = (int) (X-strlen (str))/2; Forces a conversion to a signed direction (the compiler defaults to the exact opposite), so that the division instruction is compiled into Idiv. We know that the same state of two memory units, with the symbolic processing instructions Imul, idiv and other results, and the use of unsigned processing instructions Mul,div and other results obtained, is very different. So it's a matter of symbolic unsigned computation, especially when there's a nasty auto-shift, so be careful. (The automatic conversion here, whether GCC or CL is not prompted ...) )
To avoid these errors, it is advisable to make sure that your variables are signed at the time of operation. Finish

Some of the content is reproduced from:
http://blog.csdn.net/xuezhongfenfei/article/details/8351838
And to modify, annotate and expand the content, thanks to the original author's sharing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.