SW 개발

[x86 / NASM] nasm 으로 string 함수 구현 : 예제소스

. . . 2011. 4. 21. 10:51
반응형
  • 191001 마크다운 변환완료

이전에 비트컴퓨터에서 숙제로 작성했던소스..허접소스이니 주의부탁;;

예제코드로 보는것이 가장편하다

asm 소스

str_tok 를 asm 으로 구현

str_tok.asm

segment .data
    L1 DD 0 ;  전역 포인터 1개 선언

segment .text
    global _str_tok

_str_tok

    push    ebp
    mov     ebp,esp

    mov     edi, [ebp+8]        ; 첫번째 인자 // string
    mov     esi, [ebp+12]       ; 두번째 인자 // source
    mov     ecx,0               ; 카운터 할 int 초기화

    sub     esp, 8              ; 지역 변수 2개 선언

    ; ebp-4 => sbegin
    ; ebp-8 => send

    cmp     edi,0

    jz      init_global_var         ; 전역으로 초기화 코드 실행.

    mov     [ebp-4], edi            ; sbegin = edi
                                    ; null 아니면 지역변수 초기화

routin01:
    jmp     str_spn         ; str_spn 호출


; 전역 변수있을때 전역변수로 초기화.
init_global_var:
    mov     ebx , [L1]
    mov     [ebp-4], ebx        ; sbegin = 전역변수
    jmp     routin01                ; 루틴시작


;=================================================================
; * spr_spn 코드 실행 [edi => ebp-4] 바꿈
;=================================================================

str_spn
    mov     edi, [ebp-4]        ; 첫번째 인자
    mov     esi, [ebp+12]       ; 두번째 인자
    mov     ecx,0               ; 카운터 할 int 초기화


spn_loop1:
    mov     esi, [ebp+12]           ; esi증가시켰던거 복원
    cmp     byte[edi],0             ; 종료조건
    jz      spn_return_result       ; 문자열 끝까지 비교시 끝


; 비교 시작 루틴
spn_loop2:
    mov     al, byte[esi]           ; 일단 al로 저장
    cmp     al,0                    ; 종료조건
    jz      spn_return_result           ; 같은것이 한개도 없다면..

    mov     bl, byte[edi]           ; edi bl로 저장
    cmp     al, bl                  ; 비교하고
    jz      spn_loop0               ; 같으면 같을때 루프로 점프

    inc     esi                     ; 다르면 esi증가시키고
    jmp     spn_loop2               ; 다시 비교루틴 시작


;   같을때 조건 시작
spn_loop0:
    inc     edi             ; 같으니 edi 증가시키고
    inc     ecx             ; 같으니 카운팅하고
    jmp     spn_loop1       ; 다시 루프 시작


spn_return_result:
    mov     eax, ecx        ; 그동안 카운트 한것을 반환.

;========================================================


routin02:
    add     [ebp-4], eax    ; sbegin += strspn(sbegin,del)

    mov     ebx,[ebp-4]
    cmp     byte[ebx],0     ; *sbegin == 0
    jz      zero_result

;====================================================================
; * spr_pbrk 코드 실행 [edi => ebp-4] 바꿈
;====================================================================

str_pbrk
    mov     edi, [ebp-4]        ; 첫번째 인자
    mov     esi, [ebp+12]       ; 두번째 인자
    mov     ecx,0            ; 카운터 할 int 초기화

pbrk_loop1:
    mov     esi, [ebp+12]           ; 일단 증가 시켰던 esi 복원
    cmp     byte[edi],0             ; 종료조건 문자열 끝까지 비교시 끝
    jz      pbrk_return_result      ; 종료


pbrk_loop2:
    mov     al, byte[esi]       ; esi al로 저장해서
    cmp     al,0                ; 종료조건:같은것이 한개도없다면
    jz      pbrk_loop_dif       ; 루프 다시 시작


    mov     bl, byte[edi]           ; edi bl로 저장해서
    cmp     al, bl                  ; 비교
    jz      pbrk_return_result      ; 같으면.. 바로 종료

    inc     esi         ; 틀리니 다시..
    jmp     pbrk_loop2  ; 다시 루프 돌아라

;   루프 다시 시작 루틴
pbrk_loop_dif:
    inc     edi         ; 한개 비교끝났으니 증가시켜서
    jmp     pbrk_loop1  ; 다시 루프 돌아라

pbrk_return_result:
    mov     eax,edi     ; 최초로 같은거 나온 부분 리턴

;===============================================================================


routin03:
    mov     dword[ebp-8],eax        ; send = strpbrk( sbegin, del)


routin04:
    mov     ebx,[ebp-8]
    cmp     byte[ebx],0     ; if (send && *send )
    jz      tok_result

routin05:
    mov     ebx,[ebp-8]
    mov     byte[ebx],0     ; *send = 0
    inc     dword[ebp-8]    ; send 증가.


tok_result
    pop     dword[L1]       ; ebp-8 pop
    pop     eax         ; ebp-4 최종 리턴.


    mov     esp, ebp
    pop     ebp

    ret

zero_result:

    pop     dword[L1]       ; ebp-8 pop
    pop     eax             ; ebp-4 최종 리턴.

    mov     dword[L1],0     ; curr = 0
    mov     eax,0           ; return 0

    mov     esp, ebp
    pop     ebp

    ret

테스트용 C소스

해당 어셈코드를 다음과같은 코드로 테스트가능

testapp.c

#include <stdio.h>
#include <stdlib.h>

char string[] = "www.bit.co.kr";
char seps[]   = ".";
char *token;

void main( void )
{

   token = strtok( string, seps );
   while( token != NULL )
   {
      printf( "%s", token );
      token = strtok( NULL, seps );
   }
}
반응형