Analyze the C language from a multiplication method, and analyze the C language by multiplication.
I encountered a very strange problem yesterday. First, let's look at this Code:
1 #include<stdio.h> 2 int main(int argc,char *argv[]) 3 { 4 long num1 = 203879; 5 long long num2 = 203879; 6 7 long long res1 = num1 * num1; 8 long long res2 = num2 * num2; 9 10 printf("res1 = %lld\n",res1);11 printf("res2 = %lld\n",res2);12 13 return 0;14 }
The program running result is as follows:
It seems strange that 203879 does not exceed the range of 4 bytes, but its square is over, so I store its results in an 8-byte number, why does the final result still show overflow?
Then I wrote another program and analyzed its assembly code? The procedure is as follows:
1 int main(int argc,char *argv[]) 2 { 3 long muln = 203879; 4 long long mulnl = 203879; 5 6 long long num1 = 203879 * 203879; 7 long long num2 = muln * muln; 8 long long num3 = mulnl * mulnl; 9 10 return 0;11 }
Here I divide it into three situations: one is a direct Integer as the multiplier, the other is a long integer as the multiplier, and the other is a long integer as the multiplier, then calculate their square respectively. The result of gdb debugging is as follows:
The first two cases have exceeded, and only the third case is normal. Then let's take a look at their assembly code. This is the assembly code I decompiled using the objdump:
1 int main(int argc,char *argv[]) 2 { 3 8048394: 55 push %ebp 4 8048395: 89 e5 mov %esp,%ebp 5 8048397: 83 e4 f8 and $0xfffffff8,%esp 6 804839a: 83 ec 30 sub $0x30,%esp 7 long muln = 203879; 8 804839d: c7 44 24 0c 67 1c 03 movl $0x31c67,0xc(%esp) 9 80483a4: 00 10 long long mulnl = 203879;11 80483a5: c7 44 24 10 67 1c 03 movl $0x31c67,0x10(%esp)12 80483ac: 00 13 80483ad: c7 44 24 14 00 00 00 movl $0x0,0x14(%esp)14 80483b4: 00 15 16 long long num1 = 203879 * 203879;17 80483b5: c7 44 24 18 71 b1 90 movl $0xad90b171,0x18(%esp)18 80483bc: ad 19 80483bd: c7 44 24 1c ff ff ff movl $0xffffffff,0x1c(%esp)20 80483c4: ff 21 long long num2 = muln * muln;22 80483c5: 8b 44 24 0c mov 0xc(%esp),%eax23 80483c9: 0f af 44 24 0c imul 0xc(%esp),%eax24 80483ce: 89 c2 mov %eax,%edx25 80483d0: c1 fa 1f sar $0x1f,%edx26 80483d3: 89 44 24 20 mov %eax,0x20(%esp)27 80483d7: 89 54 24 24 mov %edx,0x24(%esp)28 long long num3 = mulnl * mulnl;29 80483db: 8b 44 24 14 mov 0x14(%esp),%eax30 80483df: 89 c1 mov %eax,%ecx31 80483e1: 0f af 4c 24 10 imul 0x10(%esp),%ecx32 80483e6: 8b 44 24 14 mov 0x14(%esp),%eax33 80483ea: 0f af 44 24 10 imul 0x10(%esp),%eax34 80483ef: 01 c1 add %eax,%ecx35 80483f1: 8b 44 24 10 mov 0x10(%esp),%eax36 80483f5: f7 64 24 10 mull 0x10(%esp)37 80483f9: 01 d1 add %edx,%ecx38 80483fb: 89 ca mov %ecx,%edx39 80483fd: 89 44 24 28 mov %eax,0x28(%esp)40 8048401: 89 54 24 2c mov %edx,0x2c(%esp)41 8048405: 89 44 24 28 mov %eax,0x28(%esp)42 8048409: 89 54 24 2c mov %edx,0x2c(%esp)43 44 return 0;45 804840d: b8 00 00 00 00 mov $0x0,%eax46 }
First, let's look at the num1 code (16 ~ 20 rows), 203879 (31C67H) Square is 41566646641 (9AD90B171H), the compiler calculates the result directly, then retrieves the four bytes of the result and stores it in num1, then, use the symbol bit to fill in the 4-byte height.
Next let's take a look at the num2 code (21 ~ 27 rows). First, it stores 203879 in eax, and then stores the square result of multiplication in eax. Because eax is a 32-bit, therefore, four characters in height are removed during storage, and only four bytes are saved. The next step is to determine what the symbol bit of this number is, and then use the shift operation to get 32 1 s stored in edx, finally, the edx value is stored in the four high bytes of num2.
OK. Through the above assembly code analysis, we will analyze this code from the concept of C language:
Long num2 = muln * muln;
First, muln is a 4-byte integer, and then the result obtained by muln * muln is also a four-byte INTEGER (overflow occurs here ), then convert the result to an 8-byte integer and store it in num2. Therefore, the final result we get is also an overflow result.
After the analysis, I found that this is a long journey, and now I don't know how to do it. I like to disassemble it when I encounter something...