본문 바로가기

42cursus

libasm - 참고 자료 위주로 정리하기 (42seoul)

0. 프로젝트 목표

- nasm을 이용해서 libc 함수 구현하기

-> ft_strlen, ft_strcmp, ft_strcpy

-> ft_write, ft_read

-> ft_strdup

 

 

 

1. 학습

nasm을 설치하고 HelloWorld찍기

www.nasm.us/

 

NASM

Latest version Stable 2.15.05 History Builds List Snapshots Latest, List For users of RPM-based Linux distributions (e.g. Fedora, Red Hat, SUSE, ...), you can download the official NASM builds using dnf or yum by installing nasm.repo in your /etc/yum/yum.r

www.nasm.us

https://www.notion.so/libasm-179fc489b80a4363996490c65e9f11a7

 

calling convention에 대해서 얄팍하게 알아보기

1. 함수 반환은 rax에 저장

2. 매개변수는 순서대로 [ rdi, rsi, rdx, rcx, r8, r9 ] 라고 함 ("최대가 6개다.."라는 글을 어디서 봄)

3. 즉, 매개변수가 있는 함수를 호출 할 때는 위의 레지스터에 값을 설정하고 호출하면 됨

4. ret만나면 caller로 돌아감

 -> 모두 알 필요는 없음

cs.lmu.edu/~ray/notes/nasmtutorial/

 

nasmtutorial

NASM Tutorial Yep, it’s a tutorial. Scope of the Tutorial This tutorial will show you how to write assembly language programs on the x86-64 architecture. You will write both (1) standalone programs and (2) programs that integrate with C. We won’t get t

cs.lmu.edu

 

문법 공부해보기

 -> HelloWorld를 출력하는 예제를 실행해보면 각종 구문이 많이 나옴

 -> 깊이는 알 필요없지만 어느정도는 알고 가야 함

1
2
3
4
5
        global    _symbol            ; 심볼 만들기, _필요
        section    .text            ; 코드 영역
        extern    _malloc            ; 외부 함수
_symbol :                        ; 레이블 붙이기 (like goto format)
label... :                        
cs

- global은 함수심볼을 외부에 던지기 위함

- underscore는 macOS에서는 강제된다고 함

- section .text 는 실제 코드를 위한 섹션 (cf, section .data 는 상수나 초기화 값을 위한 섹션)

- 외부 함수는 extern 으로 가져와서 call함

https://cs.lmu.edu/~ray/notes/nasmtutorial/

 

필요한 syscall 에서의 고민들 (ft_write, ft_read에서)

- write, read함수가 error를 만날 때 어느 상황이 일어나는가

 -> 즉, error를 만나면 우리는 errno을 설정해주어야 하는데 어떻게 해야 할까

 -> error를 나는 어떻게 캐치하는가

 -> ___error 함수는 무엇이고 무엇을 리턴하는 가

1. rax에 syscall code를 넣고 syscall을 함

2. syscall이 error라면 carry flag가 활성화 됨 (참고는 아래)

3. 그와 동시에 errno을 양수로 반환 (rax에는 errno이 담겨있음)

4. 그럼 나는 carry flag가 활성화 되어있으면 error label로 넘겨줌

5. error label에서는 errno가 담긴 rax을 잠시 저장하고 ___error를 호출해서 &errno을 받아옴

6. errno에 값을 넣어주고

7. mov rax, -1 후 ret하면 됨

 

 

 

2. 참고 글

cf) 레지스터를 잠시 저장할 때는 안쓰는 레지스터에 넣는다는 생각보다는 그냥 push해놓고 필요할 때 pop하는 게 좋음

 -> ___error를 사용하거나 다른 외부함수를 사용할 때 에러를 발생할 때, 임의로 사용 중인 레지스터를 push 해버리면 에러가 안남...

 -> slack에서 ryukim님 말로는 매개변수로 인식하는 경우가 있다고 함

 

cf) syscall중에 error에 대한 글 (jc 분기문으로 잡는 근거)

https://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/x86-return-values.html

www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/x86-return-values.html

 

11.4. Return Values

A system call would not be useful most of the time if it did not return some kind of a value: The file descriptor of an open file, the number of bytes read to a buffer, the system time, etc. Additionally, the system needs to inform us if an error occurs: A

www.freebsd.org

stackoverflow.com/questions/15304829/how-to-return-errno-in-assembly

>>> errno, ___error에 관한 stackoverflow

 

How to return errno in Assembly?

I have a problem to return errno in assembly. I know how to find it, but I can't return errno and a return value. If my function fails, I would return errno (sets by a system call) and -1. I have t...

stackoverflow.com

 

cf) syscall에 0x02000000에 대한 글

stackoverflow.com/questions/48845697/macos-64-bit-system-call-table

 

macOS 64-bit System Call Table

I can find a Linux 64-bit system call table, but the call numbers do not work on macOS - I get a Bus Error: 10 whenever I try to use them. What are the macOS call numbers for operations like sys_w...

stackoverflow.com

 

cf) syscall number

opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master

 

cf) 구조체에 대한 글

 -> 어셈블러는 구조체가 뭔지모름 -> 그냥 메모리 참조임

stackoverflow.com/questions/6549708/in-assembly-how-do-you-deal-with-c-struct

 

In assembly, how do you deal with C struct?

For example, how to prepare parameters for this syscall sys_wait4: asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru) 1120 { How to deal with

stackoverflow.com

 

cf) 매개변수나 call로 리턴받은 rax레지스터의 정수 음수검사

-> 무조건 cmp rax, 0 로 검사하는 것이 아님

-> 자료형에 따라 다르게 계산해야 함

-> 리턴 값이 int라면 4byte라서 eax로 검사해야 함

-> 그렇지 않으면 앞의 4바이트의 부호비트는 0이라서 항상 양수임

 

 

cf) intel VS AT&T 의 어셈블리 차이

hardner.tistory.com/22

 

Intel 과 AT&T 차이점

Intel, AT&T 어셈블리어 문법 차이점 어셈블리언어는 Intel과 AT&T 두 가지 문법을 가지고 있다. 서로 호환되지 않는 문법이기 때문에 코드 해석에 어려움을 겪을 수 있다. 각 문법의 차이에 대한 기본

hardner.tistory.com

 

cf) syscall 사용

whitesnake1004.tistory.com/2

 

시스템 호출(System Call)

시스템 호출 이란? - 시스템 호출은 대부분 시스템 콜이라고 자주 쓰임 - 시스템 콜은 응용프로그램에서 운영체제에게 어떠한 기능을 수행해 달라고 하는 하나의 수단 - 운영 체제의 커널이 제

whitesnake1004.tistory.com

 

 

3. 마무리

Windows의 32bit를 올리디버거로 까본 적이 있기 때문에 수월했음

 -> 그렇지 못한 사람은 기초적인 문법, 명령어 부터 공부를 해야 할 듯

 -> 그 후에 기본적인 함수를 작성 후 libasm에 도전하는 것이 맞는 듯

 

함수 호출 규약에 대해서는 깊게 공부하는 거 아닌 이상 특정한 상황에 대한 예외를 알아차리기 힘듦

 

libasm하면서 64bit로 처음 봄

 -> 큰 차이는 없음

 

asm -> .c 로 변환하는 과정은 많이 해봤으나

.c -> asm로 하는 과정이 좀 더 어려운 듯

 

기본적인 내용을 알고 작성하니 정말 재밌는 서브젝트였음