您的位置:首页 > 其它

Notes of Inline Assembly

2014-04-05 16:41 309 查看

Notes of Inline Assembly

Table of Contents

1 The syntax comparation of Intel ASM and AT&T ASM
2 Basic inline assembly

2.1 'asm'
2.2 '__asm__'
2.3 '__asm__ __volatile__'

3 Extended inline assembly

3.1 Some examples

1 The syntax comparation of Intel ASM and AT&T ASM

Register Naming For AT&T ASM, register names are prefixed with '%'

1:  - AT&T:  %eax
2:  - Intel:  eax


Source & Destination ordering The source is always at left and the destination is always at right.

1:  - AT&T:  movl %eax, %ebx
2:  - Intel: mov ebx, eax


Constant value or immediate value format Should be prefixed with '$' The below example is to set 'eax' to '3'

1:  - AT&T:  movl $0x3, %eax
2:  - Intel: mov eax, 0x3

The below example moves 'C' defined variable 'boo' to 'eax'

1:  - AT&T:  movl $_boo, %eax
2:  - Intel: mov eax, _boo


Operator size specification You must suffix you instruction with one of 'b', 'w', 'l' to specify your destination register width as a 'byte', 'word' or 'longword'. Otherwise, the GNU assembler will guess.

1:  - AT&T:   movw %ax, %bx
2:  - Intel:  mov bx, ax


Referencing memory C language: immd32[base + index * scale]

1:  - AT&T: immd32(base, index, scale)
2:  - Intel: [base + index * scale + immd32]
3:    + Address particular C variable
4:      - AT&T:   (_boo)
5:      - Intel:  [_boo]
6:    + Address what register point to
7:      - AT&T:   (%eax)
8:      - Intel:  [eax]
9:    + Address a variable offeset by the value of a register
10:      - AT&T:   _foo(%eax)
11:      - Intel:  [eax + _foo]
12:    + Address a value in a array of integer
13:      - AT&T:   _array(,%eax,4)
14:      - Intel:  [eax * 4 + _array]


2 Basic inline assembly

2.1 'asm'

The basic inline assembly is very simple

asm("statements");

For exmaple:

asm("nop");
asm("movl %eax, %ebx");

1:  asm ("pushl %eax\n\t"
2:       "movl $0, %eax\n\t"
3:       "popl %eax");


2.2 '__asm__'

If 'asm' conficts with something keywords in your program, you could use

1:  __asm__("statements");


2.3 '__asm__ __volatile__'

If you don't want your assembly to be optimized by assembler, add volatile keyword.

3 Extended inline assembly

The extended assembly allows input arguments and output arguments. The basic

format is as below:

1:  Format:
2:      asm ("statements : output_registers : input_registers : clobbered_registers")
3:      For the clobbered_reisters, it means that you cannot count on these registers.
4:      Their values may change.
5:  Example:
6:      asm ("cld\n\t"
7:           "rep\n\t"
8:           "stosl"
9:           : /* no output registers */
10:           : "c" (count), "a" (fill_value), "D" (dest)
11:           : "%ecx", "%edi" );


The list of register loading code which could be used.
aeax
bebx
cecx
dedx
Sesi
Dedi
Iconstant value (0 to 31)
q,rdynamically allocated register (see below)
geax, ebx, ecx, edx or variable in memory
Aeax and edx combined into a 64-bit integer (use long longs)
The differences between 'q' and 'r' in the table

'q' makes GCC to allocate 'eax', 'ebx', 'ecx' and 'edx'
'r' makes GCC also consider 'esi' and 'edi'

3.1 Some examples

1:  // Disable interrupt
2:  #define disable() __asm__ __volatile__ ("cli");
3:
4:  // Enable interrupt
5:  #define enable() __asm__ __volatile__ ("sti");
6:
7:  // arg2 = arg1 + arg1 * 4;
8:  #define times5(arg1, arg2) \
9:  __asm__ ( \
10:    "leal (%0,%0,4),%0" \
11:    : "=r" (arg2) \
12:    : "0" (arg1) );
13:
14:  // arg2 = arg1 + arg1 * 8;
15:  #define times9(arg1, arg2) \
16:  __asm__ ( \
17:    "leal (%0,%0,8),%0" \
18:    : "=r" (arg2) \
19:    : "0" (arg1) );
20:


For the {%n}, it is straightforward first-come-first-serve, left-to-right thing, mapping to 'q' and 'r'.
So it will be "0", "1", "2" … etc

1:  asm ("leal (%%ebx,%%ebx,4), %%ebx"
2:       : "=b" (x)
3:       : "b" (x) );


If you want to use reigters in extended assemly, you should prefix the register with "%%" not just "%".
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: