SISS/Assembly

조건분기명령어 JG JL 상태레지스터 SF OF

JG : Jump Greater    ( ≒ JA)

JL : Jump Less         ( ≒ JB)


: 비슷하지만 비교하는 데이터가 다름. JG, JL은 부호가 있는 부호비트, JA, JB는 부호가 없는 비트를 비교함. 


# 부호 비트 : 1 = 존재 → 가장 높은 비트가 1이라면, 즉 부호가 있는 것이라면 -로 판단. 



EAX에는 -4를, EBX에는 1을 넣고 둘이 비교하는 어셈블리를 작성한다. 

: MOV EAX, -4 / MOV EBX, 1 / CMP EAX, EBX





# EAX에 들어가있는 값? 



: EAX에는 현재 FFFFFFFC 라는 값이 들어가 있는데, F는 16진수로 16, 2진수로 하면 1111이므로, 이를 이진수로 쓰면 


1111 1111 1111 1111 1111 1111 1111 1100 


이렇게 되고, 이는 10진수로 4,294,967,292이다. 




이후, 앞의 값이 클 경우 JUMP하는 어셈블리를 작성한다. 

: JA 40100A



# 위의 값이 부호가 있는 값인지, 부호가 없는 값인지 판단하는 것은 바로 JA/JB 또는 JG/JL 명령어이다. 위에서도 언급했듯이 JA/JB는 부호가 없는, 즉 모든 값의 부호를 +로 생각하며, JG/JL은 최상위 비트가 1일 경우 -로, 0일 경우 +로 판단한다. 

   여기서 JA 명령어를 사용하였기 때문에 EAX와 EBX에 들어있는 값은 부호를 +로 판단하여 계산한다. 따라서 EAX의 값이 EBX의 값보다 커 JUMP가 실행된다. 



JA 대신 JG 명령어를 사용하여 어셈블리를 작성해보자.

: JG 40100A



여기서는 JG 명령어로 인해 EAX 값의 부호가 -이므로 EAX의 값이 더 작다. 따라서 JUMP가 실행되지 않는다. 

대신 JL 명령어를 사용하면 EAX의 값이 EBX보다 작기 때문에 JUMP 명령이 실행된다.

: JL 40100A




# CMP EAX, EBX

: EAX와 EBX의 값을 비교하는 명령어인데, 여기서 둘의 값을 비교할 때는 둘의 차를 계산한다. 두 값의 차를 계산한다는 점에서 SUB와 비슷하지만 CMP 명령은 EAX - EBX의 값을 다시 EAX에 저장하지 않는다는 점에서 차이가 있다. 

: CMP의 결과값이 0이면 Zero Flag의 값은 1, 결과값이 0이 아니면 Zero Flag의 값은 0이 된다. 



JG의 조건 : ZF = 0 AND SF = OF

ZF = 0 : EAX와 EBX의 값이 달라야 한다. (같은 건 JGE)

☞ SF = OF : Sign Flag = Overflow Flag 

 Sign Flag : CMP 결과값의 최상위 비트 - 여기서 EAX - EBX는 -5이므로 최상위 비트가 1이 되어 SF에도 1이 저장된다. 

 Overflow Flag 

: 다음을 계산하면 1000이라는 값이 발생한다. 그러나 부호가 있는 값으로 생각했을 때, 더해진 두 값의 부호는 +이지만 계산된 결과값은 -가 나오게 된다. 7 + 1을 했을 때 8이 아닌 -8이 나온 것이다. 이처럼 부호가 같은 두 값을 더했는데 결과값으로 부호가 다른 값이 나왔을 때 Overflow가 발생했다 하고, Overflow Flag의 값이 1이 된다. 




→ 따라서 SF = OF라는 것은 앞의 값이 더 작아서 - 값이 발생된 것이 아니라, Overflow가 발생했기 때문에 -가 된 것임을 알려주기 위함이다. 



이번엔 값을 바꿔 EAX에는 1을, EBX에 -4를 저장해보자. 

: MOV EAX, 1 / MOV EBX, -4




다시 처음부터 실행하게 되면, ZF = 0, SF = OF = 0이 되고, JG의 조건에 맞기 때문에 JUMP가 실행되는 것을 확인할 수 있다. 


JL의 조건 : SF ≠ OF  

→ Overflow가 일어나지 않고 앞의 값이 뒤의 값보다 작음을 알려주기 위함이다.

CMP의 결과값이 0이 되는 값의 계산 중에서 Overflow가 일어나는 값이 없기 때문에 굳이 조건에 ZF = 0 을 적지 않는다.