Learning notes embedded in GCC Assembly I

Source: Internet
Author: User

Learning notes embedded in GCC Assembly I
-- The first addition calculator for mixed Encoding
Author: shellex.
Shellex.cn & blog.csdn.net/shellex All Rights Reserved

I wrote a simple piece of code:

# Include <stdio. h>
Int main (){
Int in1 = 0, in2 = 0, out = 0;
Printf ("plz input 2 number like this: (X1 + x2)/n ");
Scanf ("% d + % d", & in1, & in2 );
ASM volatile (
"Add % 1, % 0/n/t"
"Add % 2, % 0/n/t"
"NOP/n/t"
: "= R" (out)
: "R" (in1), "R" (in2)
:
);
Printf ("% d + % d = % d./N", in1, in2, out );
Return 0;
}
//////////////////////////////////////// ///////////////////////
Enter two numbers to calculate their sum. Compile and run the program if you want to know that there is no problem.
Running result:
Plz input 2 number like this: (X1 + x2)
2 + 3
2 + 3 = 10.
Dizzy, different from what I think. Let's take a look at the assembly code (GCC can be generated with the-S parameter ).
To compile the source file ):

...
Movl $0,-4 (% EBP)
Movl $0,-8 (% EBP)
Movl $0,-12 (% EBP)
...
Movl-4 (% EBP), % edX
Movl-8 (% EBP), % eax
/APP
Add % edX, % eax
Add % eax, % eax
NOP
 
/No_app
Movl % eax,-12 (% EBP)
Movl-12 (% EBP), % eax
...
//////////////////////////////////////// ///////////////////////
The above code is only a key part and is omitted before and after. The built-in sink is between/APP and/no_app.
Editing part. As you can see, GCC first sets-4 (% EBP) and-8 (% EBP) (in1 and in2)
Put the % EDX and % eax registers, and then execute the first add so that eax stores two numbers of sums,
The second add adds eax to itself, and finally assigns the eax value to-12 (% EBP), that is
The out. function is equivalent to the following C ++ code:
Tmp1 = in1;
Tmp2 = in2;
Tmp1 + = tmp2;
Tmp1 + = tmp1;
Out = tmp1;
Of course the results are incorrect. This is because GCC does not know how to use the eax register incorrectly. He and
I do not know that % 2 and % 0 use the same register. Therefore, I add the "&" delimiter to the output part.

ASM volatile (
"Add % 1, % 0/n/t"
"Add % 2, % 0/n/t"
"NOP/n/t"
: "= & R" (out)
: "R" (in1), "R" (in2)
:
);
 
//////////////////////////////////////// ///////////////////////
Compile and execute:
Plz input 2 number like this: (X1 + x2)
2 + 3
2 + 3 = 2009143897.
There was another strange problem. Let's look at the assembly code:

Movl-4 (% EBP), % edX
Movl-8 (% EBP), % eax
/APP
Add % edX, % ECx
Add % eax, % ECx
NOP
 
/No_app
Movl % ECx, % eax
Movl % eax,-12 (% EBP)
//////////////////////////////////////// ///////////////////////
It seems that there is no problem, but it is not. The ECX register that stores the results has not started to output
(Unlike in1 and in2, it is read into EDX and eax ). Instructions for GCC to use "R"
The output variable of the delimiter, which is not read after the register is allocated as the input variable.
Value. Data shows that this behavior may be caused by at&t's compilation from the sink of the CISC architecture processor.
Programming languages, most of the Instruction Input and Output in the CISC architecture processor are obviously separated, unlike
The same operand can be output or input by the cpu Of the RISC architecture.
So I should let GCC know that my out should also enjoy the same treatment.

# Include <stdio. h>
Int main (){
Int in1 = 0, in2 = 0, out = 0;
Printf ("plz input 2 number like this: (X1 + x2)/n ");
Scanf ("% d + % d", & in1, & in2 );
ASM volatile (
"Add % 1, % 0/n/t"
"Add % 2, % 0/n/t"
"NOP/n/t"
: "= & R" (out)
: "R" (in1), "R" (in2), "0" (out)
:
);
Printf ("% d + % d = % d./N", in1, in2, out );
Return 0;
}
//////////////////////////////////////// ///////////////////////
Add the out description in the input part, and use the qualifier "0" to specify that the out is
% 0. Because GCC does not judge whether % 1 and % 3 are associated with the same variable. Therefore
Explicitly specified.
The Assembly Code is as follows.

Movl-4 (% EBP), % ECx
Movl-8 (% EBP), % edX
Movl-12 (% EBP), % eax
/APP
Add % ECx, % eax
Add % edX, % eax
NOP
 
/No_app
Movl % eax,-12 (% EBP)
//////////////////////////////////////// ///////////////////////
The output for compiling and running is also correct:
Plz input 2 number like this: (X1 + x2)
2 + 3
2 + 3 = 5.
However, it is troublesome to write a photo like this. In fact, a simpler method is to use the "+" qualifier. Table
The operands can be read and written.
 
ASM volatile (
"Add % 1, % 0/n/t"
"Add % 2, % 0/n/t"
"NOP/n/t"
: "+ R" (out)
: "R" (in1), "R" (in2)
:
);
//////////////////////////////////////// ///////////////////////
The Assembly Code is as follows:

Movl-12 (% EBP), % edX
Movl-4 (% EBP), % ECx
Movl-8 (% EBP), % eax
/APP
Add % ECx, % edX
Add % eax, % edX
NOP
 
/No_app
Movl % edX,-12 (% EBP)
 
//////////////////////////////////////// ///////////////////////
I did not expect that I had encountered so many problems at the beginning. I recorded them, even learning notes. Since
It is a note. If the readers find errors, please do not give me any further advice. Thank you for watching.

Shellex.cn & blog.csdn.net/shellex All Rights Reserved

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.