일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- jenkins
- libasm
- Dining philosopher problem
- springboot
- 42seoul
- sql
- MySQL
- swift
- Xcode
- CI
- 프로그래밍언어론
- 데이터베이스
- 오라클
- javascript
- 다이어리
- DBMS
- Spring
- 아이패드다이어리
- AI
- 네트워크
- 소켓
- 인공지능
- JPA
- 스프링부트
- 스프링부트 웹 소켓
- CD
- 리눅스
- IOS
- 스프링
- 밥먹는 철학자
- Today
- Total
Hi yoahn 개발블로그
[42Seoul/libasm] libasm 시작하기 본문
hi0seon.tistory.com/entry/42Seoullibasm-libasm-서브젝트-번역
1. 64비트 asm 사용해야 하고, 호출 규약을 따라야 한다.
정수 타입의 파라미터를 전달할 때
- 순서대로 RDI, RSI, RDX, RCX, R8, R9 까지 6개의 레지스터를 사용하고, 7개 이상이면 스택을 통해 전달
- 실수 타입의 경우는 XMM0 ~ XMM7까지 8개를 순서대로 사용
- 반환값은 정수일 때 RAX (하위 64비트), RDX(상위 64비트) 를 사용하고, 실수일때는 XMM0(하위 128비트), XMM1(상위 128비트)를 사용한다.
호출 규약
- 함수 호출 시 매개변수는 rdi, rsi, rdx, rcx, r8, r9를 통해 넘어오거나 넘겨진다.
- 매개변수의 갯수와 상관없이 이 레지스터들에 값이 들어가 있다면 오류가 날 수 있다.
- 반환값은 항상 rax에 저장된다.
2. syscall
- syscall 명령을 통해 시스템에 미리 선언되어있는 함수를 호출할 수 있다.
- syscall 코드(함수 코드 값)는 rax에 들어 있어야 하며 반환값 또한 rax에 저장된다.
- syscall 코드는 시스템마다 다르다.
Mac -> opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master
read -> 3
write -> 4
section .text
global _main
_main :
mov rax, 0x2000004
mov rdi, 1
mov rsi, msg
mov rdx, 12
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg db "hello world"
syscall 번호는 한자리 수인데, 호출할 때 앞에 200000x가 붙는 이유는 ??
>> Mac에선 syscall 번호를 여러 클래스로 나누어두었다. write, read 는 unix 클래스에 속해서 최상단 비트를 2로 설정해두었다.
-> write: 0x2000004
-> read: 0x2000003
syscall 함수는 에러가 발생하면 rax에 에러 정보를 나타내는 음수를 반환한다.
___error 함수를 호출 한 뒤 반환된 포인터가 가리키는 값[rax] 에 넣고,
rax에는 -1을 넣어 처리한다.
section .text
읽기 전용 부분
코드를 포함하고 있는 영역을 나타낸다.
global _main;
링커에게 _main 을 전역에서 접근할 수 있도록 선언
_main:
linker에게 엔트리 포인트 알려줌
section .text
global _ft_read
extern ___error
_ft_read:
{code}
외부에서 호출할 함수 앞에 _ 를 붙여야 외부에서 호출할 수 있다. (호출 규약)
외부에 정의된 함수를 사용하기 위해 extern 으로 가져와서 호출해야 함
외부에서 호출하려면 global 로 알려줘야 한다.
명령어 구성
label : <명령어> <피연산자1> <피연산자2>; 주석
- label: 명령어들의 묶음을 나타내는 이름
- 명령어: mov, add, sub, inc, dec, call, ret, cmp, jmp, push, pop, jc
jc: carry flag가 1일 때 점프 (최상위 비트 - carry flag)
carry flag가 1이면 에러이므로 에러 처리를 위한 함수 호출
(최상단 비트에서 캐리가 발생했을 때 carry flag 가 1로 설정됨)
velog.io/@sohi_5/캐리와-오버플로우-확실하게-구분하기
je: cmp(비교) 결과가 같을 때 점프
jne: cmp(비교) 결과가 다를 때 점프
Register | Counter | |||||||
64-bit | RCX | |||||||
32-bit | ECX | |||||||
16-bit | CX | |||||||
8-bit | CH | CL |
CH, CL 레지스터는 8bit 짜리 레지스터이다.
call ___error 했을 때 return 되는 값은 errno의 주소값이다.
github.com/gurugio/book_assembly_8086_ko/blob/master/README.md
www.notion.so/Libasm-f4869fe5de17402b9054a7ca06bfc79c
www.notion.so/Libasm-3c94bbc7df234499b012f6ae82b84dc2
'42 SEOUL' 카테고리의 다른 글
CI/CD 파이프라인 (0) | 2021.08.06 |
---|---|
[42Seoul / Philosophers(OS)] Mutex 와 Semaphore 차이 (0) | 2021.06.28 |
[42Seoul / subject] Philosophers 해석 (0) | 2021.06.16 |
[42Seoul/libasm] libasm 서브젝트 번역 (0) | 2021.04.30 |
[42Seoul] Cub3D 번역 (0) | 2021.03.31 |