어셈블리어를 알아야되는 부분이 있어서 기록한다.


 GCC는 전처리, 어셈블리어로 변환, 컴파일, 링크 이렇게 나뉘어지는데

 전처리는 파일로 표현되지 않고, 기본적으로 화면에 추출된다.

 어셈블리는 문법을 나뉘어서 Intel과 AT&T 문법으로 나뉜다.

 NASM과 다른 점은 NASM은 Intel류만 변환해주는 것으로 알고 있으며, Intel 문법에서 변형된 형태를 뛴다.

 하지만, GNU  AS(약자로 GAS라고 하는데, 검색하면, 다른 걸로 검색되는 문제점 때문에 그냥 GNU AS라고 치겠다.)는 리눅스에서 주로 쓰인다.(MinGW 같은 프로그램 아닌 그냥 일반적인 GCC일 경우엔, 리눅스에서만 쓰인다.)


 일단, 모든 컴파일 과정을 적혀지는 방법은 다음과 같은 명령어를 처리하면된다.


 GCC에서 --save-temp라는 옵션을 이용하면, 전처리-어셈블리어-컴파일-링크을 사용한다.


 어셈블리어는 AS라는 프로그램, 링크는 사용하는건 ld을 이용하는걸 확인 했다.(전처리, 컴파일은 어떤 프로그램을 사용하는지 모르겠다.) GCC는 파일은 통합적으로 관리하기 위한 것이지, GCC자체가 컴파일 프로그램이 아니다.


 그래서 전처리 과정과 어셈블리어 과정등을 사용해서 만들어 날 수 있다.


 어셈블리어가 Intel, AT&T가 나뉘어 진다고 한다.


 일단적으로 GNU AS는 AT&T가 형태가 나뉘어 지며, Intel을 출력하는 방법은 masm=Intel을 이용해야된다.


 결과를 다음과 같이 출력된다.


 GCC -S main.c


 AT&T문법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    .file    "main.c"
    .def    __main;    .scl    2;    .type    32;    .endef
    .section .rdata,"dr"
.LC0:
    .ascii "Hello World!\0"
    .text
    .globl    main
    .def    main;    .scl    2;    .type    32;    .endef
    .seh_proc    main
main:
    pushq    %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe    %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc    32
    .seh_endprologue
    movl    %ecx, 16(%rbp)
    movq    %rdx, 24(%rbp)
    call    __main
    leaq    .LC0(%rip), %rcx
    call    printf
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident    "GCC: (rubenvb-4.8.0) 4.8.0"
    .def    printf;    .scl    2;    .type    32;    .endef
 
cs


 GCC -S -masm=Intel main.c

 Intel 문법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    .file    "main.c"
    .intel_syntax noprefix
    .def    __main;    .scl    2;    .type    32;    .endef
    .section .rdata,"dr"
.LC0:
    .ascii "Hello World!\0"
    .text
    .globl    main
    .def    main;    .scl    2;    .type    32;    .endef
    .seh_proc    main
main:
    push    rbp
    .seh_pushreg    rbp
    mov    rbp, rsp
    .seh_setframe    rbp, 0
    sub    rsp, 32
    .seh_stackalloc    32
    .seh_endprologue
    mov    DWORD PTR 16[rbp], ecx
    mov    QWORD PTR 24[rbp], rdx
    call    __main
    lea    rcx, .LC0[rip]
    call    printf
    mov    eax, 0
    add    rsp, 32
    pop    rbp
    ret
    .seh_endproc
    .ident    "GCC: (rubenvb-4.8.0) 4.8.0"
    .def    printf;    .scl    2;    .type    32;    .endef
 
cs


 이렇게 결과가 나온다.


 이런 방법으로 어셈블리어가 돌아가는 방식과 기초는 어셈블리어 책을 참조해서 공부해야겠다.

Posted by JunkMam
,