본문 바로가기

Programming Language/Assembly

[Assembly] 어셈블리란??

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


CPU 에는 해당 프로세서에 명령을 내리기 위해 고유의 명령어 세트가 마련되어 있는데 이 명령어 세트를 기계어라고 한다. 이 기계어는 숫자들의 규칙조합임으로 프로그래밍에 상당히 난해하다. 그래서 이 기계 명령어를 좀더 이해하기 쉬운 기호 코드로 나타낸것이 어셈블리어 인데, 우리가 어셈블리를 알아야 하는 이유는 우리가 원하는 리버싱 작업을 하고자 할떄 역어셈블러나 디버거를 쓰기 마련이다.

역어셈블러는 기계어로 되어있는 파일을 읽어 들여 일정한 규칙하에 기계어를 어셈블리어로 변환해주는 것이다. 이 말을 보았을떄 한가지 의문점이 들수 있는데 "그럼 다른 언어로 작성된 프로그램은 어떡하나?" 그에 대한 대답으로 어떤 언어로 작성된 프로그램이든지 컴파일러나 어셈블러를 거쳐 OBJ파일 즉 기계어로 변환되기 떄문에 그런걱정은 할필요가 없습니다. 기계어로 변환된다는 말은 역어셈블이 가능해진다는 말이 되니깐요. 그래서 우리가 그래서 가장 중요하게 알아야 할것은 어셈블리어 입니다. 완벽하게 알 필요는 없으며 다만 읽고 뜻을 알수 있는 정도의 실력만 있으면 됩니다. 그런 의미에서 몇가지 중요한 어셈블리어를 봅시다.

 

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


 


Push: sp 레지스터를 조작하는 명령어중의 하나이다.

         스택에 데이터를 저장하는데 쓰인다.

 ex:) Push eax       : 스택에 Eax의 값을 스택에 저장한다.

 ex:) Push 20         : 즉석값인 20을 스택에 저장한다.

 ex:) Push 401F47   : 메모리 오프셋 401F47의 값을 스택에 저장한다.

 

Pop: 이또한 sp 레지스터를 조작하는 명령어중 하나이다. 스택에서 데이터를 꺼내는데 쓰인다.

 ex:) Pop eax      : 스택에 가장 상위에 있는 값을 꺼내애서 eax에 저장(Push 역순)

 

Mov: 메모리나 레지스터의 값을 옮길떄[로 만들때] 쓰인다.

 ex:) Mov eax,ebx                       : ebx 레지스터의 값을 eax로 옮긴다[로 만든다].

 ex:) Mov eax,20                         : 즉석값인 20을 eax레지스터 에 옮긴다[로 만든다].

 ex:) Mov eax,dword ptr[401F47]  : 메모리 오프셋 401F47 의 값을 eax에 옮긴다[로 만든다]

 

Lea: 오퍼렌드1의 값을 오퍼렌드2의 값으로 만들어준다.

 ex:) Lea eax,ebx                       : eax레지스터의 값을 ebx의 값으로 만든다.

 

Inc: 레지스터의 값을 1증가 시킨다.

 ex:)  Inc eax   : Eax 레지스터의 값을 1증가 시킨다.

 

Dec: 레지스터의 값을 1 감소 시킨다.

 ex:)  Dec eax  : Eax 레지스터의 값을 1 감소 시킨다.

 

Add: 레지스터나 메모리의 값을 덧셈할떄 쓰임.

 ex:) Add eax,ebx                       : Eax 레지스터의 값에 ebx 값을 더한다.

 ex:) Add eax,50                         : Eax 레지스터에 즉석값인 50을 더한다.

 ex:) Add eax,dword ptr[401F47]  : Eax 레지스터에 메모리 오프셋 401F47의 값을 더한다.

 

Sub: 레지스터나 메모리의 값을 뻇셈할떄 쓰임.

 ex:) Sub eax,ebx                      : Eax 레지스터에서 ebx 레지스터의 값을 뺸다.

 ex:) Sub eax,50                        : Eax 레지스터에서 즉석값 50을 뺸다.

 ex:) Sub eax,dword ptr[401F47]  : Eax 레지스터에서 메모리 오프셋 401F47의 값을 뺸다.

 

Nop: 아무동작도 하지 않는다.

 

Call: 프로시저를 호출할떄 쓰인다.

 ex:)  Call dword ptr[401F47]   : 메모리 오프셋 401F47을 콜한다.

 

Ret: 콜한 지점으로 돌아간다.

 

Cmp: 레지스터와 레지스터혹은 레지스터 값을 비교하기 위하여 쓰인다.

 ex:) Cmp eax,ebx                        : Eax 레지스터와 Ebx 레지스터의 값을 비교한다.

 ex:) Cmp eax,50                          : Eax 레지스터와 즉석값 50을 비교한다.

 ex:) Cmp eax,dword ptr[401F47]   : Eax 레지스터와 메모리 오프셋 401F47의 값을 비교한다.

 

Jmp: 특정한 메모리 오프셋으로 이동할떄 쓰인다.

 ex:) Jmp dword ptr[401F47]  : 메모리 오프셋 401F47 로 점프한다.

 

조건부 점프: Cmp나 Test 같은 명령어의 결과에 따라 점프한다.

 

   Je: Cmp나 Test 의 결과가 같다면 점프 

 

   Jne: Cmp나 Text 의 결과가 같지 않다면 점프

 

   Jz: 왼쪽 인자의 값이 0 이라면 점프

 

   Jnz: 왼쪽 인자의 값이 0 이 아니라면 점프 
 

   Jl: 왼쪽 인자의 값이 오른쪽 인자의 값보다 작으면 점프(부호있는)

 

   Jnl: 왼쪽 인자의 값이 오른쪽 인자의 값보다 작지 않으면(크거나 같으면) 점프 (부호있는)

 

   Jb: 왼쪽 인자의 값이 오른쪽 인자의 값보다 작으면 점프(부호없는)

 

   Jnb: 왼쪽 인자의 값이 오른쪽 인자의 값보다 작지 않으면(크거나 같으면) 점프 (부호없는)

 

   Jg: 왼쪽 인자의 값이 오른쪽 인자의 값보다 크면 점프

     

   Jng: 왼쪽 인자의 값이 오른쪽 인자의 값보다 크지 않으면(작거나 같으면) 점프

 

   Jle: 왼쪽 인자의 값이 오른쪽 인자의 값보다 작거나 같으면 점프 (부호있는)

 

   Jge: 왼쪽 인자의 값이 오른쪽 인자의 값보다 크거나 같으면 점프

 

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

 

AND 연산

대응되는 비트가 둘다 1이면 결과는 1이고 그외의 결과들은 모두 0 이 된다.

ex:)   MOV EAX,8

        AND EAX,10

:위를 계산하기 위해 우선 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000 이 되고 10은 1010 이 되고 AND 연산은 둘다 1이여야 1이 됨으로 결과는 1000 이 됩니다.

 

OR 연산

대응되는 비트중 하나가 1 또는 둘다 1이면 결과는 1이고 그외는 모두 0이 된다.

ex:) MOV  EAX,8

      OR EAX,10

:위를 계산하기 위해 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000이 되고 10은 1010이 되고

OR 연산은 한쪽 또는 양쪽둘다 1이면 1이고 그외는 모두 0 임으로 결과는 1010이 된다.

 

XOR 연산

대응되는 비트 중에서 한비트가 1이고 다른 비트가 0이면 1이 되고 두개의 비트가 1이면 0 이 되고 두개다 0 이어도 0이 된다.

ex:) MOV EAX,8

      XOR  EAX,10

:위를 계산하기 위해 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000이 되고 10은 1010이 되고

XOR 연산은 한쪽만 1이어야 1임으로 결과는 10이 된다.

 

NOT 연산


NOT 연산은 오퍼렌드의 값을 반대로 하여 준다.

ex:) MOV EAX,10

      NOT EAX

:위를 계산하기 위해 오퍼렌드의 값을 2진수로 바꾸어 주면 10은 1010이 되고 NOT 연산은 1 과 0을 반대로 하여 줌으로 결과는 0101 이 된다.

 

*Test 연산은 오퍼렌드에 영향을 주지 않으며 플래그만 세트 시키어 준다.

[출ㅇㅇㄹㅇ처] 어셈ㅁ|작성자 berg76