본문 바로가기

assembly language

[X86 어셈블리] strncmp 구현하기 / cmpsb, cmpsw, repe 명령어

문자열 비교 명령어 CMPSB, CMPSW

es:dids:si를 비교한다. std 또는 cld로 비교 방향을 결정해줄 수 있다.  std(=set direction)시 si와 di를 감소시키며 비교한다. cld(=clear direction)시 si와 di를 증가시키며 비교한다.

 

cmpsb si, di 1씩 증감 byte 단위로 비교
cmpsw si, di 2씩 증감 word 단위로 비교

 

 

반복 명령어 REP, REPE, REPZ, REPNE, REPNZ

cx 레지스터에 반복 횟수를 저장하여 사용한다. 각 명령어의 의미는 'as long as'를 넣어서 해석하면 된다. 예를 들어 REPE는 'REPeat (as long as) Equal'로 생각한다. Equal, Zero, Not Equal, Not Zero 모두 Zero flag에 의해 판단된다. Equal과 Zero는 사실 같은 의미다. Equal의 의미는 곧 서로 빼서 Zero라는 것이다. 

반복 조건은 zero flag로 판단되지만 위의 CMPSB, CMPSW와 결합하여 사용될 때는 Zero flag를 초기화 해 줄 필요는 없다. 어차피 첫번째 문자를 비교하는 순간 그에 맞게 Zero flag가 설정될 것이고 그 값에 기반하여 반복문이 돈다.

 

명령어 의미
REP Repeat
REPE Repeat as long as equal
REPZ Repeat as long as zero
REPNE Repeat as long as not equal
REPNZ Repeat as long as not zero

 

 

strncmp 구현하기

문자열 비교 명령어는 반복 명령어와 함께 묶여서 잘 쓰인다. 이를 이용해서 C의 strncmp 함수를 구현할 수 있다. MS DOS 환경에서 도는 코드다. 문자열을 비교하고 결과를 DOS함수를 호출하여 출력한다. 주의할 점은 비교할 문자열의 길이와 cmpsb, cmpsw를 잘 고려해서 구현해야 한다는 점이다. cmpsw를 사용하면 word (=2 bytes) 단위로 비교되기 때문에 더 빠르게 반복문을 돌릴 수 있지만 문자열의 길이가 홀수일 경우 마지막 비교는 쓰레기값까지 읽어 올바르지 못한 비교 결과를 산출할 수 있다.

TITLE STRNCMP

.DOSSEG
.8086
.MODEL TINY

.DATA
str0 DB "ABCDEFGHI" ;9 chars
str1 DB "ABCDEFGHI"
str2 DB "XYZXYZXYZ"
out_str_identical DB "Identical string$", 0
out_str_different DB "Different string$", 0

.CODE
.STARTUP    
    
    cld
    mov cx, 9
    mov si, offset str0
    mov di, offset str1

    repe cmpsb
    jnz DIFFERENT

    lea dx, out_str_identical
    mov ah, 9h
    jmp PRINT_RESULT

DIFFERENT:
    lea dx, out_str_different
    mov ah, 9h

PRINT_RESULT:
    int 21h

    mov ah, 4Ch
    xor al, al
    int 21h
END