TIL

20201105(목) TIL

학습 목표

libasm의 보너스 파트인 ft_atoi_base.s 작성을 위해, 어셈블리의 배열 선언과 초기화 방법 학습하기  

 

발견한 문제

배열 선언 시 bus error 발생
section	.data
	check_arr	times 128 db 0

section	.text

 data section을 text section보다 먼저 선언하자 오류가 해결되었습니다.  

 위와 같이 section .data영역에, 문자의 중복을 검사하기 위한 배열 check_arr를 선언하였으나, bus error가 발생했습니다. 정보를 찾아보았으나 선언한 문법 자체에는 오류가 없는 것으로 보여, 이전에 작성했던 hello world 예제와 마찬가지로, 섹션의 위치를 이동시켜보았는데 문제가 해결되었습니다. text 섹션이 본격적으로 코드가 시작되는 부분이라고 하는데, 작성한 코드와 text section 사이에 data section이 위치했던 것이 문제였던 것으로 추측됩니다.  

 

학습 내용 

 ft_atoi_base()를 어셈블리어로 작성하기 위해, 이전에 피신 때 작성했던 c코드를 참고하였습니다. c언어로 작성한 코드에서는, base 문자열에 중복된 문자가 등장하는지 체크하기 위해, 모든 문자를 모두 체크할 수 있는 128칸짜리 int배열을 선언했습니다. 그리고 base에 있는 문자들의 아스키코드 값을 인덱스로 삼아, 배열의 해당 번지가 0일 경우 1로 체크하여 중복되는 문자가 있는지 확인하는 방식이었습니다.  

 

어셈블리에서 배열 선언하기
section	.data
	arr1	db 0,0,0  ;char arr1[3] = {0,}
section	.bss
	arr2	resb 3      ;char arr2[3]

 이를 어셈블리어로 구현하기 위해, 우선 배열을 선언하는 방법에 대해 학습했습니다. bss 섹션과 data 섹션에서 배열을 선언할 수 있으나, bss섹션에서 배열을 선언할 경우 초기 값을 줄 수 없다고 하여, data섹션에 선언하였습니다.

 

아주 큰 배열을 선언하고 싶을 때는?

 어셈블리에서 data 섹션에 배열을 선언할 때는, arr db 0,0,0,0...와 같은 방식으로 초기값을 주어야 하는데, 선언하고자 하는 배열은 128칸짜리 배열이었기 때문에 다른 방법이 필요했습니다. times n지시어를 활용하면 뒤따라오는 문장을 n번 반복할 수 있는데, 이를 활용하여 0을 128번 입력하는 과정을 생략할 수 있었습니다.

 

다음 학습 계획

 현재까지, base인 rsi의 유효성을 검사하는 부분과, 문자열 rdi의 +-부호나 공백 문자를 스킵하는 부분을 작성한 상태입니다. 지금까지 작성한 부분에 오류는 없는지 좀 더 다양한 테스트 케이스로 검사를 진행한 뒤에, 문자열을 int형 정수로 변환하는 알고리즘을 작성할 계획입니다.  

 

참고 자료

'TIL' 카테고리의 다른 글

20210119(수) TIL  (0) 2021.01.20
20201119 (목)  (0) 2020.11.19
20201110(화) TIL  (0) 2020.11.11
20201109(월) TIL  (0) 2020.11.09
20201106(금) TIL  (0) 2020.11.06