본문 바로가기
Study Log/정보 보안

[정보 보안] 6. 어셈블리 언어 Part.2

by LOGER 2023. 9. 19.

산술연산

음수표현하기

- 최상위 비트는 부호 비트

- 2의 보수는 모든 비트를 반전시키고 1을 더하면 됨

 

Ex) -1을 표현하기

 

1. 1의 표현

0 0 0 0 0 0 0 1

2. 1의 모든 비트 뒤집기

1 1 1 1 1 1 1 0

3. 1 더하기

1 1 1 1 1 1 1 1

 

산술연산

 

add [피연산자 1] [피연산자 2]

- 피연산자 1과 피연산자 2를 더해서 피연산자 1에 저장한다

- 둘다 메모리 X

- 피연산자 1은 상수 X

 

sub [피연산자 1] [피연산자 2]

- 피연산자 1에서 피연산자 2를 빼서 피연산자 1에 저장한다

- 둘다 메모리 X

- 피연산자 1은 상수 X

 

mul [피연산자 1]

- 부호없는 정수 (unsigned)의 곱셈을 수행함

 

ex)

mul bl ; ax=al*bl

mul bx ; ax=ax*bx ; 2바이트 넘긴건 dx 저장

mul ebx ; eax=eax*ebx ; 4바이트 넘긴건 edx 저장

mul rbx ; rax=rax*rbx ; 8바이트 넘긴건 rdx 저장

 

imul [피연산자 1] 

- mul과 완전 똑같음

 

imul [피연산자 1] [피연산자 2] 

- 피연산자 1과 2를 곱해서 1에 저장함

 

imul [피연산자 1] [피연산자 2] [피연산자 3] 

- 피연산자 2와 3을 곱해서 1에 저장함

- 피연산자3에는 상수만 있어야 함

- 레지스터를 넘어가는 값은 버려짐

 

- 부호 있는 정수의 곱셈 수행

 

 

div [피연산자 1]

- 부호없는 정수 (unsigned)의 나눗셈을 수행

 

ex)

div bl ; al=al/bl ; 나머지는 ah 저장

div bx ; ax=ax/bx ; 나머지는 dx 저장

div ebx ; eax=eax/ebx ; 나머지는 edx 저장

div rbx ; rax=rax/rbx ; 나머지는 rdx 저장

 

div [피연산자 1]

- 부호있는 정수 (signed)의 나눗셈을 수행

 

ex)

div bl ; al=al/bl ; 나머지는 ah 저장

div bx ; ax=ax/bx ; 나머지는 dx 저장

div ebx ; eax=eax/ebx ; 나머지는 edx 저장

div rbx ; rax=rax/rbx ; 나머지는 rdx 저장

 

inc [피연산자 1]

- 피연산자 1에 1을 더한다

 

dec [피연산자 1]

- 피연산자 1에 1을 뺀다

 

비트연산

and [피연산자 1] [피연산자 2]

- 피연산자 1,2를 and 연산하여 피연산자 1에 저장

- and 연산은 둘다 1이여야 1을 반환, 아니면 0을 반환하는 연산

 

or [피연산자 1] [피연산자 2]

- 피연산자 1,2를 or 연산하여 피연산자 1에 저장

- or 연산은 둘중에 하나라도 1이 있으면 1을 반환, 둘다 0이여야 0을 반환하는 연산

 

xor [피연산자 1] [피연산자 2]

- 피연산자 1,2를 xor 연산하여 피연산자 1에 저장

- xor 연산은 두 값이 같으면 1, 다르면 0을 반환하는 연산

 

not [피연산자 1]

- 피연산자 1의 비트를 반전하여 다시 1에 저장 (1의 보수)

- 그냥 0과 1을 반전하는 것

 

neg [피연산자 1]

- 피연산자 1의 비트를 반전하고 1을 더해 다시 1에 저장 (2의 보수)

- 2의 보수, 즉 부호를 바꾸는 것

 

shl [피연산자 1] [피연산자 2]

shr [피연산자 1] [피연산자 2]

- 피연산자 1의 비트를 왼쪽이나 오른쪽으로 피연산자 2만큼 이동

- 벗어난 값은 버리고 새 공간은 0

- 피연산자 2에는 상수나 cl 레지스터만 올 수 있음

- 피연산자 2에는 0~31 (0~63)까지만 넣음 (넘어가면 %32 || %64  만큼으로 인식함)

 

rol [피연산자 1] [피연산자 2]

ror [피연산자 1] [피연산자 2]

- 피연산자 1의 비트를 왼쪽이나 오른쪽으로 피연산자 2만큼 이동 (rotate)

- 벗어난 값은 새 공간으로 들어옴

- 피연산자 2에는 상수나 cl 레지스터만 올 수 있음

- 피연산자 2에는 0~31 (0~63)까지만 넣음 (넘어가면 %32 || %64  만큼으로 인식함)

 

 

제어문

- if, swith, for, while 등의 흐름을 제어하는 구문

 

cmp [피연산자 1] [피연산자 2] 

- 두 연산자를 빼서 비교한다. (결과 저장 안함)

- 비교 결과에 따라 플래그가 생성됨

 

test [피연산자 1] [피연산자 2]

- 두 연산자를 and 연산하여 비교한다. (결과 저장 안함)

- 비교 결과에 따라 플래그가 생성됨

- 대부분 피연산자 1,2에는 같은 레지스터가 위치함

- 레지스터의 값이 0이라면 ZF (zero flag)가 세팅됨 (레지스터의 값이 0인지 아닌지 확인용)

 

EFLAGS 레지스터

- 산술 연산 결과 및 상태를 표현

 

Ex)

CF (Carry): 부호 없는 수의 연산 결과가 비트를 넘을 경우 설정 (자리 올림, 자리 빌림)

ZF (Zero): 연산결과가 0이면 설정

SF (Sign): 연산결과가 음수이면 설정

OF (Overflow): 연산의 결과로 인해 부호 비트가 반전되면 설정 (오버플로우, 언더플로우)

 

 

jmp [피연산자 1]

- 아무 조건 없이 피연산자 1로 점프함

 

조건 점프

- 조건 점프가 엄청 많음

 

Ex)

jz - 연산결과가 0일 때

je - 두 피연산자 같을 때

jl - (signed) 첫번째 피연산자가 더 작을 때

jb - (unsigned) 첫번째 피연산자가 더 작을 때

jg - (signed) 첫번째 피연산자가 더 클 때

ja - (unsigned) 첫번째 피연산자가 더 클 때

js - 연산 결과가 음수일 때

 

중간에 n을 넣어서 부정할 수 있음 (jnz, jne... 등)

끝에 e를 붙여서 같다는 의미를 추가 가능 (jle, jbe... 등)