IT_Programming/Assembly

[전광성의 어셈블리어 이해하기] 조건처리

JJun ™ 2007. 7. 2. 10:36
  • 시작하기에 앞서...

    본 강좌가 이제 중반에 다다르고 있다. 계절도 어느덧 가을이 되었다. 필자는 계절이 바뀔 때마다 사춘기가 온 것처럼 괜시리 마음이 들뜨며 일이 손에 잡히지 않기도 한다. 하지만 우리는 오늘 조건처리를 배우기 위해 한걸음 더 나아가야 한다. 조건처리란 무엇일까? 조건에 따라 처리를 하려면 일단은 조건이 무엇인지 판단을 해야 할 것이다. 그리고 그 판단에 따라 각각의 행동이 달라져야 한다. 이렇게 판단과 분기, 두 부분으로 나눌 수 있다. 그렇다면 그 판단은 어떻게 해야 할지 또 고급언어에서의 조건문을 어셈블리어로 어떻게 구현할지에 대해 알아볼 것이다.

  • AND 인스트럭션

    AND인스트럭션은 당연한 이야기 이지만, AND연산을 한다. 피연산자로 두 개를 받는데, 첫 번째 피연산자와 두 번째 피연산자를 AND하여 그 결과를 첫 번째 피연산자에 넣는다. 두 번째 피연산자로는 임의의 상수가 올 수 있지만, 첫 번째 피연산자로는 임의의 상수가 올 수 없다. 또 두 개의 피연산자가 모두 메모리에 존재하는 변수여서는 안된다. 한 피연산자가 변수이면 다른 피연산자 역시 변수가 될 수 없다는 뜻이다.

  • 플래그의 변화

    CPU의 레지스터에 존재하는 플래그에 대해서 이전에도 설명했지만, 워낙 중요하기에 다시한번 설명해 드리겠다. 모든 인스트럭션들은 각각 수행되고 난 후 변화시키게 될 플래그들이 정해져 있다. 이것은 아예 없을 수도 있고, 매우 많을 수도 있다. 예를 들어, AND연산에서 계산 결과가 0이었다면 Zero Flag가 세팅된다. 자주 쓰이는 플래그는 다음과 같다. 참고로, 세팅되는(set) 것은 1이 된다는 뜻이고, 그 반대는 clear라고 해서 반대로 0이 된다는 뜻이다.

    플래그

    세팅되는 경우

    Zero Flag

    연산 결과가 0일때

    Carry Flag

    '연산 결과값'이 '결과값이 들어갈 피연산자의 크기'보다 클때

    Sign Flag

    최상위 비트가 1이 될 때

    Overflow Flag

    피연산자가 부호있는 정수라는 가정하에, '연산 결과값'이 '결과값이 들어갈 피연산자의 범위'를 벗어났을 때.


    < 표 1 : 플래그 >


    지난번에도 이야기 한 바 있지만, 플래그는 일단 위에 설명한 대로 설정되지만, 이용하고 말고는 프로그래머의 몫이라는 점을 잊지 않기 바란다. 예를 들어서, 부호없는 정수형에 대한 연산을 했을 때도 최상위 비트가 1이 되면 Sign Flag는 1이 된다. 하지만 부호없는 정수에 대해 연산하였기 때문에 Sign Flag는 본래의 의미를 잃어버리고 쓸모없기 때문에 이 경우에 프로그래머는 SIgn Flag에 신경쓰지 않는다.

    또, Overflow Flag도 마찬가지다. 우리가 어떠한 피연산자로 연산을 했는지에 상관없이 Overflow Flag는 부호있는 정수에 대한 연산이었다는 가정하에 세팅된다. 따라서, 우리가 부호없는 정수에 대한 연산을 하였는데도 Overflow Flag는 세팅될 수 있지만, 신경쓰지 않아야 한다.

  • TEST 인스트럭션

    TEST는 말그대로 한번 해보는 것이다. 단도직입적으로 말하면, 결과값이 첫 번째 피연산자에 들어가지 않고 버려진다는 점을 제외하고는 AND인스트럭션과 완전히 똑같다. 그렇다면 이 인스트럭션을 왜 사용할까? 이 연산이 유일하게 변경시키는 것은 플래그이다. 간단한 예제를 보자. 우리는 al레지스터에 비트0과 비트3이 둘 다 0인지 확인해 보고 싶다. 어떻게 해야할까? 다음과 같이 0인지 확인하고 싶은 비트에 1을 적어주고 나머지에는 0을 적어준 후 test인스트럭션을 이용하면 된다.
      test al, 00001001b
    만약 al에 비트0과 비트3이 모두 0이라면 Zero Flag가 세팅(1)될 것이다. 비트0와 비트3 중 하나라도 1이라면 Zero Flag가 클리어(0)된다. 본회에서 배우게 되겠지만, 이렇게 세팅된 Flag를 이용해서 분기를 할 수 있다.

  • CMP 인스트럭션
    TEST인스트럭션과 어떤 면에서는 매우 흡사하다고 할 수 있다. 이 인스트럭션 역시 플래그를 제외하고는 절대로 값을 변경시키지 않게 된다. CMP는 comparision의 약자이다. 두 값을 비교해서 어느 놈이 큰지, 또는 두 값이 같은지 알아내려면 어떻게 해야 할까? 학창시절 수학공부를 게을리하지 않았다면 알 수 있을 것이다. a와 b라는 두 수가 있을 때, 두 값을 빼 보아서 양수이면 a가 큰 것이고, 같으면 a와 b가 같은 값을 가지며, 음수이면 b가 크다. 이런 방식을 이용해서 CMP인스트럭션은 두 수를 비교하게 된다.

    CMP인스트럭션 역시 결과값이 첫 번째 피연산자에 들어가지 않고 버려진다는 점을 제외하고는 SUB인스트럭션과 완전히 똑같다. 따라서 우리는 결과값의 플래그를 이용해서 어떤 수가 더 컸었는지를 판단하게 될 것이다. 이 판단은 다소 복잡하므로, 원리의 설명을 배제하고 방법을 표에 정리해 놓았다. 여기서, 첫 번째 피연산자는 dest이고, 두 번째 피연산자는 src이다. 또 !=기호는 같지 않다는 뜻이다.

  •