관리 메뉴

IT창고

System 명령어와 분기문 본문

보안/System

System 명령어와 분기문

방구석여포 2018. 1. 17. 23:52

명령어로는 어셈블리어의 shift연산, 논리연산, 형변환에 대해 알아보겠습니다.


shift연산에 대해 알아보겠습니다.


shift연산은 0000 0001의 숫자가 있으면 왼쪽으로 한번 shift를 할 경우 0000 0010이 됩니다.


명령어로는 shl , shr 입니다. 이 명령어를 논리shift라고합니다. 논리shift는 부호가 없는 연산을 합니다.


 

edx의 값은 4인 0100 입니다. shl 명령어로 왼쪽으로 2번 shift하게 되면 0001 0000 이되면서 2진수를 10진수로 바꾸면 값은 16임을 확인할수있습니다.


산술 shift에 대해 알아보겠습니다.

전체적인 내용은 논리shift와 같으며 단 산술shift는 부호가 있는 연산이 가능합니다.



실행파일을 실행해보면 -부호가 있는걸 확인할수있습니다.



논리연산에 대해 알아보겠습니다.

논리연산은 논리적으로 비트를 다루는 연산입니다. 명령어는 and , xor , or, neg 가 있습니다.



and연산은 그림과같이 2진수 16진수 10진수의 표현으로 masking을 할수있습니다. 레지스트의 정식적인 초기화는 xor를 사용하여 초기화하는것이 가장 좋습니다. 


형변환에 대해 알아보겠습니다.


명령어: movzx movsx


1) 큰 -> 작은


C언어 

int a = 10;

short b = a;


2) 작은 -> 큰


C언어

short a = 10;

int b = a;





숫자의 형변환을 해줄수있습니다. movzx인경우 값이 이동되며 확장된 부분에 0값을 채우고  movsx의 경우엔 확장된 부분을 부호비트로 채워넣게 됩니다. 큰수에서 작은 수로 갈때는 특정 명령어가 존재하지 않습니다. 가져올 경우 크기를 줄여 가져오는데 이때 상위 비트의 값이 손실이 일어날수있는점을 주의 합니다!



어셈블리어의 분기문(if , switch) 관계연산자에 대해 알아보겠습니다.


- cmp 명령어 (Compare)

형식은 cmp vleft, vight  -> eflags register 입니다.

cmp명령어는 레지스트나 메모리의 값을 변경하지 않고 오직 플래그 레지스터(SF부호, ZF 0혹은 두개의 값이 같은때, CF올림수)

동작은 sub vleft, vright와 같으며 범용레지스터에 연산을 저장하지만 cmp 명령어는 플래그 레지스터에만 연산의 결과를 적용시킵니다.


인텔 CPU 명령어 설명에서 플래그 레지스터에 대해 자세히 확인할수있습니다.


1) vleft가 큰 경우

- 양의 정수

- SF: 0 , ZF: 0


2) vright가 큰 경우

- 음의 정수

- SF:1 , ZF: 0


3) 같은경우 : 0

- SF: , ZF: 1


실행파일을 실행시키면 값은 20이 아닌 10의 값만 있습니다. 플래그 레지스터에만 적용된 모습인데 이번에는 pushfd로 출력해보겠습니다.


이번에는 플래그 레지스터의 값을 확인할수있습니다. 647의 값이 나왔는데 계산기 2진수로 확인해봅니다.


ZF는 7bit이고 SF는 8bit입니다. 결과 8번째 비트가 1인걸 확인할수있습니다.



이제 분기문에 대해 알아보겠습니다. 

분기문은 C언어의 제어문 if, case와 같은걸로 기계어로 보면 if나 case나 구분이 없습니다. 사실상 성능이 똑같습니다.


무조건 분기: jmp

jmp 명령어로 주소를 이동해보겠습니다. 사용형식은 jmp a입니다.



main에서 맨 첫줄에 jmp가 있습니다. 프로그램이 시작하자 마자 바로 jmp로  second 레이블로 이동하여 실행파일의 결과는 2번째 글만 출력되게 됩니다. 이걸 무조건 분기라고 합니다. C언어에서는 goto문이 이와 동일합니다.


조건 분기: j명령어

조건이 성립하면 해당 위치로 이동하고 상태는 플래그 레지스터를 보고 결정합니다.

인텔 CPU 명령어 설명서를 보면 j로 시작하는 명령어들이 굉장히 많습니다.



여기서 조건 분기에 사용할 j명령어를 골라 사용하면 됩니다.


간단하게 C언어로 아래와 같은 프로그램을 어셈블리어로 만들어 보겠습니다.

if ( a < 10 ) {

printf("less then 10\n");

}



scanf로 받는 값이 a이고 그 값이 9이하라면 출력문이 나오며 10이상이라면 출력문이 실행되지 않습니다.


이번에는 C언어로 표현하면 아래와 같은 코드를 어셈블리어로 만들어보겠습니다.

C로 표현하면 

if ( a < 10 ) {

printf("less then 10\n");

}else{

printf("bigger then 10\n");

}



else 처리는 레이블을 하나 더 만들어 숫자를 보고 만약10이상이 아니라면 jmp 명령어로 아무것도 없는 값으로 넘겨주었습니다. 


'보안 > System' 카테고리의 다른 글

System 메모리구조와 어셈블리어 함수  (0) 2018.01.22
System 어셈블리어 반복문  (0) 2018.01.18
System 어셈블리어 사칙연산  (1) 2018.01.17
System 레지스터(Register)  (0) 2018.01.16
System 어셈블리어  (0) 2018.01.12
Comments