Implicit type conversion in C language, C Language
I read a blog post, which is described as follows:
1 #include <stdio.h>
2
3 int main ()
4 {
5 unsigned short a = 1;
6 unsigned short b = 0;
7
8 if (a <(b-1)) // The result -1 of a and b-1 is converted to int type for comparison, 1 <-1, obviously false
9 {
10 printf ("in if \ n");
11}
12
13 return 0;
14
15}
"In if" is printed in the expected results, but nothing is output during actual running. Change the following code to output "in if", which is consistent with the expectation.
1 #include <stdio.h>
2
3 int main ()
4 {
5 unsigned short a = 1;
6 unsigned int b = 0;
7
8 if (a <(b-1)) // The result of b-1 is converted to 0xffffffff, 1 <0xffffffff, obviously true.
9 {
10 printf ("in if \ n");
11}
12
13 return 0;
14
15}
Use assembler to directly compare the two results (the company is not secure from sending Internet images ..), the main differences are found in the following five rows. The short is extended in the first four rows, from 2 bytes to 4 bytes, and the short is increased to 0. The reason for the non-conformity between the running result and expectation lies in row 5th: jge 8048461
1 08048425 <main>:
2 8048425: 8d 4c 24 04 lea 0x4(%esp),%ecx
3 8048429: 83 e4 f0 and $0xfffffff0,%esp
4 804842c: ff 71 fc pushl -0x4(%ecx)
5 804842f: 55 push %ebp
6 8048430: 89 e5 mov %esp,%ebp
7 8048432: 51 push %ecx
8 8048433: 83 ec 14 sub $0x14,%esp
9 8048436: 66 c7 45 f6 01 00 movw $0x1,-0xa(%ebp)
10 804843c: 66 c7 45 f4 00 00 movw $0x0,-0xc(%ebp)
11 8048442: 0f b7 45 f6 movzwl -0xa(%ebp),%eax
12 8048446: 0f b7 55 f4 movzwl -0xc(%ebp),%edx
13 804844a: 83 ea 01 sub $0x1,%edx
14 804844d: 39 d0 cmp %edx,%eax
15 804844f: 7d 10 jge 8048461 <main+0x3c>
16 8048451: 83 ec 0c sub $0xc,%esp
17 8048454: 68 00 85 04 08 push $0x8048500
18 8048459: e8 a2 fe ff ff call 8048300 <puts@plt>
19 804845e: 83 c4 10 add $0x10,%esp
20 8048461: b8 00 00 00 00 mov $0x0,%eax
21 8048466: 8b 4d fc mov -0x4(%ebp),%ecx
22 8048469: c9 leave
23 804846a: 8d 61 fc lea -0x4(%ecx),%esp
24 804846d: c3 ret
25 804846e: 66 90 xchg %ax,%ax
There are no symbols for the values in the Assembly, but the commands are signed separately. The jge used above is a symbolic comparison method, resulting in the comparison result: if (1 <-1), false, no string is printed
Command |
Description |
Operator number |
Jbe |
Unsigned below or equal (lower or same) |
<= |
Jae |
Unsigned above or equal (higher or same) |
> = |
Jb |
Unsigned below (lower) |
< |
Ja |
Unsigned above (higher) |
> |
Jle |
Signed less or equal |
<= |
Jge |
Signed greater or equal |
> = |
Jl |
Signed less |
< |
Jg |
Signed greater |
> |