Studying!!/공부를하자

어셈블리 strcmp_length strcmp_byte 구현

ashch 2008. 10. 17. 00:07
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 값을 출력한다.