본문 바로가기

Studying!!/공부를하자

어셈블리 strcmp_length strcmp_byte 구현

0. 개관

strcmp_length.s 경우:

문자열 길이로 비교.
문자열의 길이가 같고, 1byte당 값도 같으면 0 return.
문자열의 길이가 다르고 test code상의 변수 in1이 길면 1 return, 더 짧으면 -1 return.
만약 문자열의 길이가 같고, 1byte당 값이 다를 경우 앞에서부터 차이가 나는 순간의 in1와 int2의 해당 byte값을 비교하여 in1의 값이 더 크면 1 return. 더 작으면 -1 return.

strcmp_byte.s 경우:

바이트코드(아스키코드) 크기 비교(일반적인 C언어에서 사용하는 strcmp() 함수와 동일)
앞에서부터 char 1byte씩 비교 후 다르다면, 거기서 멈추고 return. 이 때 return값은 test code상의 변수인 in1-in2 return. (즉, 앞 char 아스키코드 - 뒤 char 아스키코드 값)
문자열의 길이가 같고 byte당 값이 같다면 역시 in1-in2 return (즉, 0 return)


1. 소스코드

-strcmp_byte.s

AREA |.text|, CODE, READONLY

EXPORT strcmp_byte

strcmp_byte

LDRB r2,[r0],#1 ;parameter r0주소의 in1을 byte단위로 r2에 load

LDRB r3,[r1],#1 ;parameter r1주소의 in1을 byte단위로 r3에 load

CMP r2,r3

BNE return3 ;r2와 r3가 동일한 값 가지지 않으면 return으로 branch

CMP r2,#0

BEQ return3 ;r2가 0이면(즉, r2의 값이 더 없으면) return으로 branch

B strcmp_byte

return3

SUB r0, r2, r3 ;r2-r3의 결과 값을 return(바이트 크기 비교)

MOV pc,lr

END




-strcmp_length.s

AREA |.text|, CODE, READONLY

EXPORT strcmp_length

strcmp_length

MOV r4, #0

MOV r5, #0

strcmp_length_loop

LDRB r2,[r0],#1 ;parameter r0주소의 in1을 byte단위로 load

LDRB r3,[r1],#1 ;parameter r0주소의 in2을 byte단위로 load

CMP r2, r3

MOVGT r5, #1 ;r2와 r3이 동일 값 아니면 1 저장

MOVLT r5, #-1 ;r2와 r3이 동일 값 아니면 -1 저장

CMP r4, #0

MOVEQ r4, r5 ;r4가 0일 때만 r5값 저장

CMP r2, #0

BEQ return1

CMP r3, #0

BEQ return2

B strcmp_length_loop

return1 ;r2와 0이 같을 경우(즉, r2값이 더 이상 없을 때)

CMP r3, #0

MOVNE r0, #-1 ;r3가 더남아있으므로 -1 리턴

MOVEQ r0, r4 ;r3도 더 남아있지 않다면, r4값 리턴(최상위 byte 차이기준)

MOV pc,lr

return2 ;r3와 0이 같을 경우(즉, r3값 더이상 없고, r2값 남았을때)

MOV r0, #1

MOV pc,lr

END





2.소스코드설명

-strcmp_length.s

1. 처음에 r4와 r5에 각각 0을 저장한다.
2. 스트링의 길이를 비교하는 함수는 먼저 레지스터 r0, r1에 저장되어 있는 메모리의 주소 값에서 r2, r3로 각각 load하고나서, 1을 더한다. (post-indexing방식)
3. r2와 r3값을 비교하여 만약 다르다면 r5에 그 값을 저장한다. 그리고 r4가 0이라면 r5값을 r4에 넘긴다.(즉, r4는 최초 한번 값을 받거나 아니면 영원히 0이다.) 이는 후에 두 스트링 type의 input이 만약 동일한 길이라면, 이 앞에서부터 기준으로 차이가 났을 때 값에 따른 strcmp_lenth결과를 출력하게 하기 위해서이다.
4. r2와 0을 비교하여 r2의 값이 더 남아 있는지 없는지 확인하고, 0이라면(r2값이 더 남아있지 않다면, return1로 branch 한다. 그리고 label return1에서 r3와 0을 비교하여 r3값이 더 남아있는지 확인 후에 더 남아있으면 뒤의 값이 더 길다는 의미므로 -1을 return. r3값이 더 남아있지 않다면 저장해둔 r4값을 return한다.
5. r2와 0을 비교하고 더 남아있다면 r3와 0을 비교한다. 만약 r3값이 더 남아있지 않다면 label return2로 가서 무조건 1을 return한다.(왜냐하면 전 명령에서 r2는 남아있다는 것을 알기 때문이다) 만약 r3값이 더 남아있다면, loop를 돈다.

-strcmp_byte.s

처음은 동일하다.
1. 스트링의 길이를 비교하는 함수는 먼저 레지스터 r0, r1에 저장되어 있는 메모리의 주소 값에서 r2, r3로 각각 load하고나서, 1을 더한다. (post-indexing방식)
2. r2와 r3값을 비교하여 만약 다르다면 label return3로 바로 branch하고, r2-r3값을 return 한다.
3. r2와 r3값이 만약 같다면, r2값과 0을 비교한다. 이는 r2값이 더 이상 값이 남아있는지 없는지 아닌지를 알기 위해서이다. 여기서 더 이상 없다면, return3로 branch 한다. 그리고 r2-r3값을 return 한다.(r3값은 따로 비교할 필요가 없다. r2보다 짧다면, 2번에서 먼저 branch 했을 것이고, r2와 동일하다면, 역시 0을 return 할 것이다. r2보다 더 길다면, 0-해당r3byte를 하여 음수 값을 return 할 것이다.)
4. 2, 3번에서 branch 하지 않았다면 loop를 돈다.

-test_strcmp.c

1. extern int strcmp_byte(char *a, char *b); 선언
extern int strcmp_length(char *a, char *b); 선언
2. ret_byte는 strcmp_byte()의 return 값이고, ret_length는 strcmp는 strcmp_length() return 값이다. 둘다 int type이다. input이 되랴 스트링 변수 in1, in2를 선언한다.(char in1[], in2[];) 각각에 비교할 string를 초기 값으로 넣고 test한다.
3. 처음 byte단위 문자열 비교함수에 들어가 return하고, 다음 length 기준으로 문자열 비교함수에 들어가 return 한다. 각각의 경우 후에 printf함수를 이용해 return 값을 출력한다.








'Studying!! > 공부를하자' 카테고리의 다른 글

어셈블리 Linked List Operation (insert/remove/sort/search/empty)  (0) 2008.11.18
Linux Scheduler 분석  (0) 2008.11.17
Code Optimizing  (0) 2008.10.15
어셈블리 GCD  (0) 2008.10.07
CPU 정보를 보여주는 모듈만들기  (0) 2008.09.26