Assembly
Intel x86 Architecture ( windows ) 연산 방향 ←
AT&T Architecture ( *-NIX계열 ) 연산 방향 → ( * gdb가 아니라 objdump에서 확인해야 함 )
Inline Assembly
```c
int input = 3;
int output = 0;
__asm__ __volatile__(
"mov %1, %%eax \n\t"
"add $1, %%eax \n\t"
"mov %%eax, %0 \n\t"
: "=r" (output)
: "r" (input)
: "eax"); // clobber
```
- output / input / clobber를 사용하는 경우(Extended asm), asm에서 레지스터를 사용할 때 반드시 ``c %%``로 적어주어야 한다.
반대로 Basic asm을 사용하는 경우 반드시 ``c %``로 적어주어야 한다. - output / input 구분 없이 좌측부터 순서 대로 ``c %0, %1, ...`` 으로 번호가 매겨지기 때문에 asm 내에서 접근할 때는 이 번호로 접근하면 된다.
- eax의 경우 clobber로 명시해주지 않아도 잘 동작하는 것 같기는 하다.
output / input Constraints
clobber
etc
``c "instruction \n\t"``
``c \n``만 쓰거나, ``c ;``을 써도 명령어로 인식이 되기는 되는데, `` .s``파일에서 보기 안좋다.
``c __asm__``
`` ( )`` 안의 내용이 인라인 어셈블리로 작성된다는 것을 명시한다.
ANSI 표준은 `` __asm__``이므로 이를 사용하는 것이 좋지만
gcc에서는 `` asm``만 써도 잘 동작하며 kernel에서도 ``c asm volatile``을 사용한다.
``c __volatile__``
컴파일러가 최적화 하지 않고 인라인 어셈블리로 작성한 어셈블리 그대로 둔다.
``c __declspec(naked)``
VC++에서만 지원하고 gcc에서는 지원하지 않는 키워드다.
`` __volatile__``은 `` __asm__``에 붙어 적용 범위가 `` __asm__``이고 ``c __declspec(naked)``는 함수에 붙어 적용 범위가 함수라는 차이점이 있다.
gcc에 비슷한 기능의 ``c __attribute__((naked))``가 있기는 하지만 ARM 등만 지원하고 x86은 지원하지 않는다.
instructions
```c
"push $0x00000000 \n\t"
"push $0x61626364 \n\t"
"call 0x5d0ba0e7 \n\t"
```
```c
db "/asdf", 0x00
```
1byte 씩 직접 쓰는 명령어.
위처럼 문자열을 적는 경우 아스키 코드가 들어가며 `` ,``로 hex값을 직접 넣어줄 수 있다.
쓰는 단위에 따라 `` dw, dd, dq...`` 명령어도 있다.
```c
xchg %ebx,%edi
```
두 레지스터의 값을 교환한다.
```c
sar eax, 1
```
shift arithmetic right로, C의 `` >>``와 동일하다. 산술 연산이기 때문에 채워지는 bit가 MSB에 의존한 값이라 음수에 사용해도 ``c /2``한 효과를 보장한다.
pointer
```c
jmp *%eax
jmp (%eax)
jmp *(%eax)
```
모두 기계어 코드가 다르다.
연산 결과도 다를 것 같은데, 아직 확인안해봤다.
windows에서는 ``c *``연산자를 못본 것 같고, linux에서만 확인했다.
mov & lea
- `` mov :`` Load Value
- `` lea :`` Load Effective Address
lea와 mov는 어떻게 사용하느냐에 따라 똑같이 동작할 수 있다.
lea의 두번째 operand에는 레지스터만 올 수 있다.
```c
mov %esp, %eax
```
esp의 값을 eax에 저장.
eax에 stack 주소가 들어가며 esp와 같은 곳을 가리키게 된다.
```c
mov %esp, (%eax)
```
esp의 값을 eax가 가리키고 있는 곳에 저장.
즉 eax는 주소값을 저장하고 있어야 하며 어딘가를 가리키고 있어야 한다.
```c
mov (%esp), %eax
```
esp가 가리키고 있는 곳의 값을 eax에 저장.
가장 일반적인 사용일 듯.
```c
lea 0x4(%esp), %eax
```
esp의 값에 4를 더한 값을 eax에 저장.
결국 eax에 저장되는 것은 주소다.
```c
mov 0x4(%esp), %eax
```
esp의 값에 4를 더한 값이 가리키는 곳의 값을 eax에 저장.
결국 eax에 저장되는 것은 data다.
'Languages & Frameworks > C C++' 카테고리의 다른 글
exec 계열 함수 (0) | 2017.05.01 |
---|---|
fork - exec / wait +clone (0) | 2017.05.01 |
[C] printf, scanf계열 (0) | 2016.11.10 |
[C] atoi / strtol , sprintf : 문자열 > 숫자, 16진수 변환 (2) | 2016.11.06 |
Pointer (0) | 2016.09.14 |