Use intel-style inline assembly in GCC

Source: Internet
Author: User

It is very simple to use ASM (". intel_syntax noprefix/N ") declare that later inline assembly can use intel style. When constructing executable files, add the-MASM = intel parameter to GCC.
First, write a small program to test it:
# Include <stdio. h> <br/> int main () {<br/> int A = 3; <br/> ASM (". intel_syntax noprefix/N "); <br/> ASM (" mov dword ptr a, 10/N "); <br/> printf (" % d/N ", a); <br/> return 0; <br/>}
[Root @ jcwkylk SRC] # gcc-MASM = intel test. C-o Test
/Tmp/ccgwtkuf. O: In function 'main ':
Test. c :(. Text + 0x1a): Undefined reference to 'A'
Collect2: LD returned 1 exit status
Error. symbol A is not defined. Let's see what the compiled result looks like:
[Root @ jcwkylk SRC] # gcc-s test. c
The output is not long. paste all content of test. S:
. File "test. C "<br/>. section. rodata <br/>. lc0: <br/>. string "% d/N" <br/>. text <br/>. globl main <br/>. type main, @ function <br/> main: <br/> Leal 4 (% ESP), % ECx <br/> andl $-16, % ESP <br/> pushl-4 (% ECx) <br/> pushl % EBP <br/> movl % ESP, % EBP <br/> pushl % ECx <br/> subl $36, % ESP <br/> movl $3,-8 (% EBP) <br/> # app <br/>. intel_syntax noprefix <br/> mov dword ptr a, 10 <br/> # no_app <br/> movl-8 (% EBP), % eax <br/> movl % eax, 4 (% ESP) <br/> movl $. lc0, (% ESP) <br/> call printf <br/> movl $0, % eax <br/> addl $36, % ESP <br/> popl % ECx <br/> popl % EBP <br/> Leal-4 (% ECx), % ESP <br/> RET <br/>. size main ,. -Main <br/>. ident "GCC: (GNU) 4.1.1 20061011 (Red Hat 4.1.1-30)" <br/>. section. note. GNU-stack, "", @ progbits
As shown above, the part between # app and # no_app is. intel_syntax, which remains unchanged, and a in the Code is originally a local variable. It is dynamically allocated on the stack only when the function is running, and accessed using EBP with an offset, this is the problem. Because the global variable name is saved in the symbol table, you can only use the global variable name to use the variable name in inline assembly. It is unreasonable to change a local variable into a global one to access the variable by name in the inline assembly. Therefore, we also use EBP + offset to access the local variable here.
To do this, you need to understand how the stack is allocated for the function during GCC compilation, and what the register conventions are like when calling the function. From the assembly code above, we can see that:
Main: <br/> Leal 4 (% ESP), % ECx; ECx = [esp + 4], <br/> andl $-16, % ESP <br/> pushl-4 (% ECx) <br/> pushl % EBP <br/> movl % ESP, % EBP <br/> pushl % ECx <br/> subl $36, % ESP
These lines of code are used to initialize the call stack of the MAI function. Unlike the CL compiler, several lines are added before the push EBP, and an ESP & =-16 operation is performed, -16 = 0xfffffff0, which may be used for alignment. ESP should maintain 16-byte alignment. However, these details have little effect here. These three lines are the most important:
Pushl % EBP
Movl % ESP, % EBP
Pushl % ECx
There is an operation to press the ECX register stack, so the starting address of the first local variable should be the ebp-8.
Another note is the call of printf:
Movl-8 (% EBP), % eax
Movl % eax, 4 (% ESP)
Movl $. lc0, (% ESP)
Call printf
In this Code, printf has two parameters but does not see the expected push. GCC uses another method: directly operate ESP. The above three lines of code, the first [ebp-8] is the first local variable that is a value to eax, and then pass this value to the ESP + 4 address pointing to the memory unit, ESP then points to the first parameter of printf-the format control string. After that, call printf will push the address of the next instruction into the stack and jump to printf. Therefore, for printf, EBP + 4 is still the return address, and EBP + 8 is still the first parameter, EBP + 0xc is still the second parameter. Everything has not changed.
The last line of code is movl $0, % eax.
It seems that the returned value is still stored in the eax register.
Well, now I want to write a complete test program:
# Include <stdio. h> <br/> int add (int A, int B) {<br/> return a + B; <br/>}< br/> int main () {<br/> int A = 3; <br/> ASM (". intel_syntax noprefix/N "); <br/> ASM (" mov dword ptr [ebp-8], 10/N "); <br/> printf (" % d/N ", a); <br/> ASM ("Push dword ptr [ebp-8]/n"); <br/> ASM ("Push 25/N "); <br/> ASM ("Call Add/N"); <br/> ASM ("add ESP, 8/N "); <br/> ASM ("mov dword ptr [ebp-8], eax/N"); <br/> printf ("% d/N", ); <br/> return 0; <br/>}
[Root @ jcwkylk SRC] # gcc-MASM = intel test. C-o Test
[Root @ jcwkylk SRC] #./test
10
35

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.