-
[libasm] 어셈블리 (about 1 week) - 2일차(ft_write, ft_read)42seoul 2021. 5. 6. 16:47
어셈블리 2일차
NASM flag (-f macho64)
- -f : format Specifies the output file format. To see a list of valid output formats, use the -hf option.[man page]
- macho는 파일 포맷임 -> OS X에서 사용하는 실행 파일(Mach-O)[참고 블로그]
ft_read & ft_write 에러 처리
syscall을 실행하고 나서 에러가 났으면 jc를 이용해서 err 함수를 호출한다.(혹은 에러가 나지 않은 경우만 end로 함수를 끝낸다.)
err 함수의 구성을 보면 (다른 사람들 코드 보니) 크게 두가지 방법이 있다.
push, pop 하는 방법과 다른 변수 이용하여 errno 저장하기이다.
첫번째 방법은 스택에 던져놨다가 다시 가져오기이고 두번째 방법은 다른 변수를 이용하니까 코드 줄이 더 길다.
스택에 던져놨다 가져오기가 요즘 많이 쓰는 방법인듯하다.
jc에 대한 설명
어셈블리는 1 bit짜리 상태 레지스터를 가지고 있음(C, P, A, Z, S, T ... 등)
함수 호출 후에 이 상태 레지스터들을 보고 에러가 났는지 안났는지 알 수 있다.
JE나 JZ 명령어는 Z(zero) flag를 살펴보고 다음줄을 실행하는 명령어고
JC는 C(carry) flag를 살펴보는 명령어다.
Jump short if carry (CF=1) Carry flag는 올림을 나타내는 플래그로, 계산에서 빌림이나 올림이 발생하면 1로 세팅된다.
그런데 Carry flag랑 syscall이랑 무슨 상관이지?[출처]
답:
The convention that BSD-based operating systems generally follow is that the kernel system call (#1) will set or clear the carry flag according to whether an error occurred. If no error occurred, rax contains the system call's return value (here, the number of bytes read); if an error did occur, eax contains the error code (it's normally a 32-bit value, since errno is an int). So if you are writing in assembly, that is what you should expect to see.
해석:
BSD 기반 운영 체제가 일반적으로 따르는 규약은 커널 시스템 호출 (#1)이 에러가 발생했는지에 따라 Carry 플래그를 설정하거나 지운다는 것이다. 오류가 발생하지 않으면 rax에는 시스템 호출의 반환 값(여기서 읽은 바이트 수)이 포함되고, 오류가 발생한 경우 eax에는 오류 코드(errno는 int이므로 일반적으로 32비트 값)가 포함됩니다. 그래서 만약 여러분이 어셈블리를 사용하고 있다면, Carry 플래그를 신경쓰면 된다.
시스템콜 모양이 이런 이유 (ex : 0x2000004)
즉 시스템콜들이 Mach용, Unix/BSD용 등의 클래스로 나눠져있고,
write나 exit등은 UNIX 시스템콜에 해당하므로, 클래스는 2에 해당.
그러므로 (2000000 | 00FFFFFF & 유닉스시스템콜번호), 즉
유닉스 시스템콜 번호에 2000000를 더한 형태인 2000001 (exit),
2000004 (write)가 시스템 콜 번호가 됨.
pop qword[rax]에서 Qword를 왜 쓰는지? 알아보기
pop qword[rax]는 스택에 있는 data를 가져와서 rax 레지스터에 들어있는 주소에다가 넣으려고 쓴 코드이다.
operation은 크기 명시가 필요해서 써주는 거고, 64bit니까 qword 써준다.
qword대신 dword쓰면 에러남(64비트가 기본인데 그 미만을 레지스터이용해서 옮기려고 하면 안된다고 함)
ft_write.s:17: error: instruction not supported in 64-bit mode
크기 명시안해도 오류남
ft_write.s:16: error: operation size not specified
'42seoul' 카테고리의 다른 글
[Philosophers] 필로소퍼 70시간만에 끝내기(1)-과제파악하기 (0) 2021.05.18 [libasm] 어셈블리 (about 1 week) - 2일차(ft_strlen, ft_strcmp) (0) 2021.05.06 [libasm] 어셈블리 (about 1 week) (0) 2021.03.26 [cub3d] map parse 맵 파싱하기 (0) 2021.03.21 [minishell] Shell이란? 그리고 Shell이 하는 일 (0) 2021.03.01