Analyze the C language from a multiplication method, and analyze the C language by multiplication.

Source: Internet
Author: User

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...

Related Article

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.