본문 바로가기

Programming/C/C++

C/리눅스 어셈블리 프로그래밍 - 1

반응형
기초적인 리눅스 어셈블리 프로그래밍
몇가지 예제와 기본적인 주석과 매크로 사용법만 적었습니다.

>>> return 0;
1
2
3
4
5
6
7
8
9
10
11
segment .text
    global _start
_start:
    mov eax, 1
    mov ebx, 0
    int 0x80
 
segment .data
 
segment .bss
 

>>> db의 데이터 print
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
segment .text
    global _start
_start:
    ; \n
    mov eax, 4
    mov ebx, 1
    mov ecx, init
    mov edx, 1
    int 0x80
 
    ; print
    mov eax, 4
    mov ebx, 1
    mov ecx, my ; 
    mov edx, 10 ; 글자(9+ \n(1)
    int 0x80
 
    ; exit
    mov eax, 1
    mov ebx, 0
    int 0x80
 
segment .data
    init db 0xa
    my db 'hyeonbell'0xa
 
segment .bss


실행 결과

>>> (어셈블링).asm 파일을 .o 파일로 변환.
  • nasm -f elf32 [파일이름].asm
    • nasm : 어셈블러
    • nasm가 지원하는 포맷 : nasm -hf 명령으로 확인.
>>> (링킹) 실행파일 생성.
  • ld -m elf_i386 -o t1 t1.o
    • ld : 링커
>>> 라인주석
  •  " ; " 사용
>>> print 하기

>>> objdump로 보기 : objdump -D [실행파일] -M intel

>>> 64bit 빌드
  • nasm -f elf64 t1_2.asm
  • ld -m elf_x86_64 -o t1_2 t1_2.o
>>> resb
  • reserved byte 의 뜻
  • [이름] resb [수]
    • [이름]의 [수]만큼을 예약하겠다는 뜻
>>> 입력 받기 : mov eax, 3
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
32
33
34
35
segment .text
    global _start
_start:
    ; print
    mov eax, 4
    mov ebx, 1
    mov ecx, init_p
    mov edx, 15
    int 0x80
 
    ;input data
    mov eax, 3 ; input
    mov ebx, 0
    mov ecx, a ; 주소
    mov edx, 3 ; 3만큼 받음
    int 0x80
 
    ; input print
    mov eax, 4
    mov ebx, 1
    mov ecx, a
    mov edx, 3
    int 0x80
 
    ; exit
    mov eax, 1
    mov ebx, 0
    int 0x80
 
 
segment .data
    init_p db 'input 3 char : ' 
 
segment .bss
    a resb 2


실행 결과
>>> define, 정의 매크로
  • [이름] equ [값]
  • ex) SYS_EXIT equ 1
>> db 길이를 받는 매크로
1
2
3
segment .data
    init_p db 'INPUT your initial : '
    init_p_len equ $ -init_p

>> 정의하여 가시성 높이기 : 이니셜 받는 프로그램
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
SYS_EXIT equ 1
SYS_READ equ 4
SYS_WRITE equ 3
SYS_IN equ 0
SYS_OUT equ 1
 
segment .text
    global _start
_start:
    ; print
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, init_p
    mov edx, init_p_len
    int 0x80
 
    ; input
    mov eax, SYS_WRITE
    mov ebx, SYS_IN
    mov ecx, a
    mov edx, a_len
    int 0x80
 
    ; print a
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, a
    mov edx, a_len
    int 0x80
 
    ; print line
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, line
    mov edx, line_len
    int 0x80
 
    ; exit
    mov eax, SYS_EXIT
    mov ebx, 0
    int 0x80
 
segment .data
    init_p db 'INPUT your initial : '
    init_p_len equ $ -init_p
    line db 0xa
    line_len equ $ -line
 
segment .bss
    a resb 3
    a_len equ $ -a

실행 결과

>>> 입력값을 더하는 프로그램
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
SYS_EXIT equ 1
SYS_READ equ 4
SYS_WRITE equ 3
SYS_IN equ 0
SYS_OUT equ 1
 
segment .text
    global _start
_start:
    ;print init_p
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, init_p
    mov edx, init_p_len
    int 0x80
 
    ; input number1
    mov eax, SYS_WRITE
    mov ebx, SYS_IN
    mov ecx, input1
    mov edx, 1
    int 0x80
 
    mov eax, SYS_WRITE
    mov ebx, SYS_IN
    mov ecx, xx
    mov edx, 1
    int 0x80
 
    ; print init_p
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, init_p
    mov edx, init_p_len
    int 0x80
 
    ; input number2
    mov eax, SYS_WRITE
    mov ebx, SYS_IN
    mov ecx, input2
    mov edx, 1
    int 0x80
    
    mov eax, SYS_WRITE
    mov ebx, SYS_IN
    mov ecx, xx
    mov edx, 1
    int 0x80    
 
 
    ; sum
    mov eax,[input1]
    sub eax, '0'
    mov ebx,[input2]
    sub ebx, '0'
    add eax,ebx
    add eax, '0'
    mov [sum], eax
 
    ;print 
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, input1
    mov edx, 1
    int 0x80
 
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, r1_p
    mov edx, r1_p_len
    int 0x80
 
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, input2
    mov edx, 1
    int 0x80
 
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, r2_p
    mov edx, r2_p_len
    int 0x80
 
    mov eax, SYS_READ
    mov ebx, SYS_OUT
    mov ecx, sum
    mov edx, 1
    int 0x80
 
    mov eax, SYS_EXIT
    mov ebx, 0
    int 0x80
 
segment .data
    init_p db 'INPUT Number : '
    init_p_len equ $ -init_p
    r1_p db ' + '
    r1_p_len equ $ -r1_p
    r2_p db ' = '
    r2_p_len equ $ -r2_p
 
segment .bss
    input1 resb 1
    input2 resb 1
    sum resb 1
    xx resb 1

실행 결과
>> 오류가 많다.
  • 십의 자리 이상은 제대로 계산 안됨


반응형