반응형

** macos, intel syntax 기준 ** 

section .text
	global _ft_read
	extern ___error

_ft_read:
	mov rax, 0x2000003
	syscall
	jc _err
	ret

_err:
	push rax
	call ___error
	pop rdx
	mov [rax], rdx
	mov rax, -1
	ret

 

read()를 재구현해놓은 어셈블리 코드다. 위 코드를 바탕으로 에러를 처리하는 방법을 정리한다. 

 

 

syscall로 read 함수 호출하기 

_ft_read:
	mov rax, 0x2000003
	syscall

 

rax에 넣어놓는 값에 따라 syscall로 호출되는 함수가 다르다. 1은 exit, 4는 write. 여기선 read() 함수를 호출하기 위해, rax에 3을 넣어둔다.

출처 : https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master

 

참고로 그냥 3이 아닌 0x200003인 이유는 macos에선 syscall에 클래스를 두기 때문. macosx나 bsd는 system call 번호를 여러 ‘class'로 나눠뒀다. read나 write는 syscall_class_unix에 속하기 때문에 upper bits 를 2로 설정한다. 즉 unix system call 의 system call 은 (0x2000000 + unix syscall #)가 된다.

 

 

에러 처리 구문으로 넘어가기 

	jc _err
	ret

 

syscall 함수는 rax에 error value를 리턴한다. 오류가 있을 경우 작은 음수 (-1 ~ -4095)를 내뱉는다고 한다. 이는 unsigned int 값을 벗어나는 연산 결과이므로, carry flag가 참이 된다. 따라서 jc(carry flag가 1일 때 점프)를 활용하면 에러 처리 구문(_err)로 넘어갈 수 있다.

 

 

___error 이용해 에러 처리 하기

_err:
	push rax
	call ___error
	pop rdx
	mov [rax], rdx
	mov rax, -1
	ret

 

먼저 rax에 담겨있는 error value를 push해 스택에 백업해둔다. 그 다음에 ___error 함수를 호출하면 에러 주소값이 rax에 담긴다. rdx에 스택에 저장시켜 놨던 error value를 팝해온다. 

 

rdx에 담긴 error value를 에러 주소를 변경하지 않고 고대로 집어 넣기 위해 `mov [rax], rdx` 해준다. rax에 []를 씌워주면 주소는 건들지 않고 값만 바꿀 수 있다.

 

그리고 마지막으로 return value는 -1이 돼야 하므로 rax에 -1을 넣고 반환한다. 

 

**잘못된 정보가 있으면 댓글 주십셔**

반응형
  1. minckim 2020.09.16 14:49

    잘 보고 갑니다!

  2. taekkim 2020.10.08 14:16

    에러 처리 구문이 이해가 안되고 있었는데 잘보고 가여ㅎ

  3. hseo 2020.10.21 13:38

    깔끔한 정리 정말 감사합니다. 제가 이해가 잘 가지 않는 부분이 있는데요.. 에러 함수 부른 후 rax의 값으로 error value를 넣었는데 , 그 뒤에 rax에 다시 -1의 값을 넣으면 덮어씌워지는 개념이 아닌건가요..? 적어주신 코드 컴파일하면 errno가 잘 세팅되긴 하는데요..

    • yechoi 2020.10.21 22:52 신고

      전 -1은 주소값이 다른 별개의 것이라 생각했는데요, 주소값을 직접 찍어 확인해본 건 아니라 확실하지는 않습니다. 클러스터에서 한번 확인해봐야겠어요...! 결과가 나오면 또 공유할게요

    • MLDD 2020.11.04 02:04 신고

      아직 컴파일을 안해봤는데, 혹시 음수 값인데, mov 말고 movsx를 쓰는게 맞을까요? 아니면 mov로 충분히 음수값을 보낼 수 있을까요?

    • yechoi 2020.11.04 07:47 신고

      양수나 음수나 바이트수가 같아서 상관없을 듯해요

  4. MLDD 2020.11.04 01:24 신고

    혹시 extern ___error 와 _err 처리 관련해서 참조할 만한 원문 같은게 있을까요? 한번 그쪽도 살펴보고 싶어서요.
    친절한 설명 감사합니다.

    • yechoi 2020.11.04 07:53 신고

      assembly errno 검색하면 나오는 스택 오버플로우 게시글들을 참고했어요 ~

  5. jiseo 2020.11.05 00:43

    아.. 여기 정모네요
    잘보고갑니다

+ Recent posts