summaryrefslogblamecommitdiffstats
path: root/md/writeup/gcc_inline_assembly.md
blob: 808268c53669da7bdd5adabc589ed33c13b277cf (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                          







                                                                                
    



























































































                                                                
    











                                                                         
       



                       
    









                         
       





                                                 
    


















                                                                                                                                  

                                   
    















                                      










                                   

                                                                                                    
    




                              














                                                                   
title: GCC inline assembly

# GCC inline assembly

Here is attempt to make best notes about gcc inline asm. As this is just small
operator that is for long time, i dont thing there is some full guide how to use
it lets do it here for wisdom of internet.

## Inline assembly syntax

```c
asm [volatile] ( 
        AssemblerTemplate
        : OutputOperands
        [ : InputOperands
        [ : Clobbers ] ]
)
```

### Output operands

| Option | Note |
|---|---|
| "=r" | Write output to register |

### Input operands

| Option | Note |
|---|---|
| "r" | Input to register |

### Clobbers 

Clobbers used to tell GCC that registers are used. 

| Clobber option | Note |
|---|---|
| "0" | map to register "0" same register |

### Modifiers

|Modifier|Specifies|
|---|---|
| = | Write-only operand, usually used for all output operands |
| + | Read-write operand, must be listed as an output operand |
| & | A register that should be used for output only |

### Table of register names

Table of AMD64 register names

```text
+---+--------------------+  
| r |    Register(s)     |  
+---+--------------------+  
| a |   %eax, %ax, %al   |  
| b |   %ebx, %bx, %bl   |  
| c |   %ecx, %cx, %cl   |  
| d |   %edx, %dx, %dl   |  
| S |   %esi, %si        |  
| D |   %edi, %di        |  
+---+--------------------+  
```

|Register|Name|
|---|---|
| rax | %%rax |
| rbx | %%rbx |
| rcx | %%rcx |
| rdx | %%rdx |
| rdi | %%rdi |
| rsi | %%rsi |
| rbp | %%rbp |
| rsp | %%rsp |
| r8  | %%r8  |
| r9  | %%r9  |
| r10 | %%r10 |
| r11 | %%r11 |
| r12 | %%r12 |
| r13 | %%r13 |
| r14 | %%r14 |
| r15 | %%r15 |

## Syscall calling convention

<!--### Intel i386 Linux-->

### Intel AMD64 Linux

| Param | Register |
| --- | --- | 
| 1th            | __rdi__ |
| 2th            | __rsi__ |
| 3th            | __rdx__ |
| 4th            | __rcx__ |
| 5th            | __r8__  |
| 6th            | __r9__  |
| syscall number | __rax__ |

## Example

### AMD64 Add two numbers

```c
int32_t a=1,b=2,c=-1;
asm(	
	"movl %1, %0\n\t"
	"addl %2, %0\n\t"
	:"=r"(c)
	:"r"(a),"r"(b)
	:"0");
```
__a__,__b__ - use regisers and save result __c__ to register, 
make to use for __c__ same register by mentioning "0" in clobber register

__Output__
```text
	movl %edx, %edx
	addl %ecx, %edx
```

```c
int32_t a=1,b=2,c=-1;
asm(	
	"movl %1, %0\n\t"
	"addl %2, %0\n\t"
	:"=r"(c)
	:"g"(a),"g"(b)
	:"0");
```

__Output__
```text
	movl -4(%rbp), %edx
	addl -8(%rbp), %edx
```

### AMD64 Call linux syscall mmap with inline asm

```c
long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off)
{
	long ret;
	asm(
		"mov %p6, %%r9\n\t"
		"mov %p5, %%r8\n\t"
		"mov %p4, %%r10\n\t"
		"mov %p3, %%rdx\n\t"
		"mov %p2, %%rsi\n\t"
		"mov %p1, %%rdi\n\t"
		"mov $9, %%rax\n\t"
		"syscall\n\t"
		:"=a"(ret)
		:[p1]"m"(addr),[p2]"m"(len),[p3]"m"(prot),[p4]"m"(flags),[p5]"m"(fd),[p6]"m"(off));
	return ret;
}
```
Put result of execution to __ret__, all paramters in memory

### Intel random number with RDRAND

```c
uint64_t get_hw_rand()
{
	uint64_t ret;
	int i=0;
	const int timeout = 10;
	while (i<timeout)
	{
		asm("rdrand %0\n\t"
			:"=a"(ret)::);
		if (ret) break;
		i++;
	}
	return ret;
}
```

<!--

### Intel i386 BSD
### Intel AMD64 BSD
### ARM
### MIPS

-->

## Switching on of intel/att syntax

Inline assembler for GCC by default uses AT&T syntax. There is possible to turn on/off intel syntax.

```c
asm(".intel_syntax noprefix");
asm("mov eax, 1");
asm(".att_syntax prefix");
```

## Asm goto



## Links

1. https://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
2. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
3. https://en.wikipedia.org/wiki/Inline_assembler
4. http://www.ethernut.de/en/documents/arm-inline-asm.html
5. http://wiki.osdev.org/Inline_Assembly
6. http://asm.sourceforge.net/articles/rmiyagi-inline-asm.txt
7. http://wiki.osdev.org/Inline_Assembly/Examples
8. http://wiki.osdev.org/Calling_Conventions