'AssemBly'에 해당되는 글 3건

  1. 2020.04.10 :: [AssemBly] 메모리 기초강의
  2. 2020.04.10 :: [AssemBly] 기본적인 명령어 모음
  3. 2020.04.10 :: [AssemBly] 기초 명령어 소개
AssemBly 2020. 4. 10. 16:19

* 사용 CPU, 문법

- intel 32bit, intel 문법

** 어셈블리어 문법은 두가지가 있다

- Intel 문법 (윈도우에서 사용)

- AT&T 문법 (리눅스에서 사용)

1. RAM , ROM

메모리는 크게 RAM  ROM 으로 나뉜다.

1.1 RAM (Random Access Memory)

- 휘발성 ( 전원이 꺼지면 저장되었던 데이터들이 모두 사라짐)

- 컴퓨터의 주기억장치

- 응용 프로그램의 일시적 로딩

- 데이터의 일시적 저장

- 읽고 쓰는 속도가 매우 빠르다

1.2 ROM (Read Only Memory)

- 불휘발성 ( 전원이 꺼져도 데이터가 남아있음 )

- 고정기억장치

- 컴퓨터의 동작순서 같은 데이터 저장

2. CPU, RAM, Hard Disk

컴퓨터의 메인보드를 살펴보면 CPU의 주변에 RAM이 존재하고(ram을 꽂을 수 있는 메모리 슬롯) 제법 떨어진 곳에 Hard Disk가 존재하는 것을 볼 수 있다.

그렇다면 왜 Hard Disk 가 아닌 RAM이 주기억장치 일까?

2.1 비교

메모리는 그 속도가 CUP와 근접할 수록 빠르다.

속도의 순위를 매기자면

1. register (cpu 내부에 존재)

2. ram

3. hard disk

하지만 용량은 그 순위의 역순이다.

hard disk는 그 용량이 크지만 속도가 너무 느리기 때문에 주기억장치가 될 수 없으며, register는 속도가 매우 빠르지만 용량이 너무 적기 때문에 ram이 주기억장치가 된것이다.

3. RAM의 작동방식 (memory의 작동방식) - 가독성을 위해 한줄씩 띄어쓰기 함.

CPU는 RAM에서 데이터를 받아 연산을 수행한다. 그렇다면 RAM의 작동방식은 어떠할까?

3.1 CPU와 RAM

1 bit 의 메모리를 1개의 상자라고 생각하자.

그렇다면 8bit(1byte)의 메모리는 상자 8개의 묶음(이음)일 것이다.

메모리를 늘리기 위해선 그저 상자를 추가하면 된다.

만약 1GB의 메모리가 있다면 그것은 8 * 1024 * 1024 * 1024 = 8589934592 개의 상자로 이루어졌다고 생각하면 된다.

RAM의 CPU에서 정보를 전달해주어야 하기 때문에 상자마다 CPU와 연결되어 있다고 가정하자.

그렇다면 CPU와 RAM 사이에는 8589934592개의 연결이 필요하다.

실제로 CPU와 RAM은 CPU의 핀으로 정보를 주고 받는데 이 핀이 8589934592개라면 CPU의 크기가 굉장히 커야 할 것이다.

따라서 RAM과 CPU의 연결은 bit 하나하나의 연결이 아닌 하나의 주소와의 연결로 이루어져 있다.

3.1.1 메모리 주소

하나의 주소는 하나의 상자 묶음을 가리킨다. (한쌍)

상자묶음의 크기는 그 PC의 운영체제 ( 16bit, 32bit, 64bit )에 따라 다르며, 만약 32bit 운영체제라면 상자묶음의

크기가 32bit, 즉 32개의 상자로 이루어져 있다는 것을 뜻한다.

ram의 크기는 주소와 상자묶음 한쌍의 갯수를 의미한다. 즉, 4GB 짜리 ram에는 각기 다른 주소와 상자묶음이 한 쌍으로 8 * 4G 개 있다는 것이다.

4GB RAM >>

0 - ㅁㅁ....ㅁㅁ

1 - ㅁㅁ....ㅁㅁ

.

.

.

8*4G -2 - ㅁㅁ .... ㅁㅁ

8*4G -1 - ㅁㅁ .... ㅁㅁ (0부터 시작하니까 -1을 해준다)

4. MOV 명령어와 메모리주소

메모리 주소의 표기법 = [ 주소 ]

Ex ->

[00402001] , [02130423] 등..

4.1 OllyDbg로 주소 보기

주소는 Hex 값(16진수)

- 왼편 : Address 16의 1승 자리 씩 증가

- 오른편 : 왼편의 Address에 대한 16의 0승 자리의 나열

4.2 mov 명령어와 메모리 주소

Ex ->

mov [0040200], eax

** 주의사항

'mov 메모리, 메모리' (불가)

-> 1. mov reg, 메모리

2. mov 메모리, reg (가능)

4.3 메모리 크기 지정

위의 명령어를 입력하면 명령어가 자동으로 아래의 사진처럼 변경된다.

mov [402000], eax

-> mov dword ptr ds:[402000], eax

 

이것은 reg의 크기에 따라 달라지는데...

mov dword ptr ds:[402000], eax

mov word ptr ds:[402000], ax

mov byte ptr ds:[402000], al

여기서 dword, word, byte에 대해 알아보겠다.

4.3.1 DWORD, WORD, BYTE

BYTE 는 말그대로 1 byte의 크기를 의미한다.

WORD 는 2byte의 크기를 의미하고

DWORD 는 4byte의 크기를 의미한다.

이것은 각각 register의 크기에 맞추어 명령어에 들어가야할 필수 입력 정보이다.

dword - eax

word - ax

byte - al,ah

그러나 이것은 편의를 위해 사용자가 mov [402000], eax 만 입력을 하더라도 디버거가 자동으로 reg의 크기를 읽어 앞에 붙여준다.

4.3.2 WORD가 2byte인 이유.

DWORD는 사실 32bit 운영체제가 되면서 만들어진 것이다.

16bit 운영체제 당시 WORD는 16bit를 의미하였으며 이 전통이 32bit 운영체제가 되면서까지 이어진 것이다.

4.3.3 PTR

명령어를 다시 보면 dword 뒤에 ptr이란것이 붙는다. c언어를 공부했다면 ptr이 포인터를 의미한다는 것을 알 것이다.

뒤에 붙은 ptr은 앞에 붙은 용량을 뜻하는 문자와 합쳐져

"지금 이 명령은 피연산자(operand)의 용량중 dowrd 만큼의 공간을 이용합니다!" 라는 뜻을 갖는다.

4.3.4 메모리 크기 지정은 반드시 필요하다.

디버거가 mov [주소], reg 의 명령에서는 reg의 크기를 읽어서 자동으로 메모리 크기 지정을 해주지만 reg가 아닌 직접 값을 집어 넣으려고 할때는 반드시 직접 메모리 크기 지정을 해주어야 한다.

Ex ->

= 불가

= 가능

'AssemBly' 카테고리의 다른 글

[AssemBly] 기본적인 명령어 모음  (0) 2020.04.10
[AssemBly] 기초 명령어 소개  (0) 2020.04.10
posted by 핵커 커뮤니티
:
AssemBly 2020. 4. 10. 16:16

기본적인 어셈블리 명령어

명 령 어

설 명

Data Transfer

MOV

Move

데이터 이동 (전송)

PUSH

Push

오퍼랜드의 내용을 스택에 쌓는다

POP

Pop

스택으로부터 값을 뽑아낸다.

XCHG

Exchange Register/memory with Register

첫 번째 오퍼랜드와 두 번째 오퍼랜드 교환

IN

Input from AL/AX to Fixed port

오퍼랜드로 지시된 포트로부터 AX에 데이터 입력

OUT

Output from AL/AX to Fixed port

오퍼랜드가 지시한 포트로 AX의 데이터 출력

XLAT

Translate byte to AL

BX:AL이 지시한 데이블의 내용을 AL로 로드

LEA

Load Effective Address to Register

메모리의 오프셋값을 레지스터로 로드

LDS

Load Pointer to DS

REG←(MEM), DS←(MEM+2)

LES

Load Pointer ti ES

REG←(MEM), ES←(MEM+2)

LAHF

Load AH with Flags

플래그의 내용을 AH의 특정 비트로 로드

SAHF

Store AH into Flags

AH의 특정 비트가 플래그 레지스터로 전송

PUSHF

Push Flags

플래그 레지스터의 내용을 스택에 쌓음

POPF

Pop Flags

스택으로부터 플래그 레지스터로 뽑음

Arithmetic

ADD

Add

캐리를 포함하지 않은 덧셈

SBB

Subtract with Borrow

캐리를 포함한 뺄셈

DEC

Decrement

오퍼랜드 내용을 1 감소

NEG

Change Sign

오퍼랜드의 2의 보수, 즉 부호 반전

CMP

Compare

두 개의 오퍼랜드를 비교한다

ADC

Add with Carry

캐리를 포함한 덧셈

INC

Increment

오퍼랜드 내용을 1 증가

AAA

ASCII adjust for Add

덧셈 결과 AL값을 UNPACK 10진수로 보정

DAA

Decimal adjust for Add

덧셈 결과의 AL값을 PACK 10진수로 보정

SUB

Subtract

캐리를 포함하지 않은 뺄셈

AAS

ASCII adjust for Subtract

뺄셈 결과 AL값을 UNPACK 10진수로 보정

DAS

Decimal adjust for Subtract

뺄셈 결과의 AL값을 PACK 10진수로 보정

MUL

Multiply (Unsigned)

AX와 오퍼랜드를 곱셈하여 결과를 AX 또는 DX:AX에 저장

IMUL

Integer Multiply (Signed)

부호화된 곱셈

AAM

ASCII adjust for Multiply

곱셈 결과 AX값을 UNPACK 10진수로 보정

DIV

Divide (Unsigned)

AX 또는 DX:AX 내용을 오퍼랜드로 나눔. 몫은 AL, AX 나머지는 AH, DX로 저장

IDIV

Integer Divide (Signed)

부호화된 나눗셈

AAD

ASCII adjust for Divide

나눗셈 결과 AX값을 UNPACK 10진수로 보정

CBW

Convert byte to word

AL의 바이트 데이터를 부호 비트를 포함하여 AX 워드로 확장

CWD

Convert word to double word

AX의 워드 데이터를 부호를 포함하여 DX:AX의 더블 워드로 변환

Logic

NOT

Invert

오퍼랜드의 1의 보수, 즉 비트 반전

SHL/SAL

Shift logical / arithmetic Left

왼쪽으로 오퍼랜드만큼 자리 이동 (최하위 비트는 0)

SHR

Shift logical Right

오른쪽으로 오퍼랜드만큼 자리 이동 (최상위 비트 0)

SAR

Shift arithmetic Right

오른쪽 자리이동, 최상위 비트는 유지

ROL

Rotate Left

왼쪽으로 오퍼랜드만큼 회전 이동

ROR

Rotate Right

오른쪽으로 오퍼랜드만큼 회전 이동

RCL

Rotate through Carry Left

캐리를 포함하여 왼쪽으로 오퍼랜드만큼 회전 이동

RCR

Rotate through Carry Right

캐리를 포함하여 오른쪽으로 오퍼랜드만큼 회전 이동

AND

And

논리 AND

TEST

And function to Flags, no result

첫 번째 오퍼랜드와 두 번째 오퍼랜드를 AND하여 그 결과로 플래그 세트

OR

Or

논리 OR

XOR

Exclusive Or

배타 논리 합 (OR)

String Manipulation

REP

Repeat

REP 뒤에 오는 스트링 명령을 CX가 0이 될 때까지 반복

MOVS

Move String

DS:SI가 지시한 메모리 데이터를 ES:DI가지시한 메모리로 전송

CMPS

Compare String

DS:SI와 ES:DI의 내용을 비교하고 결과에 따라 플래그 설정

SCAS

Scan String

AL 또는 AX와 ES:DI가 지시한 메모리 내용 비교하고 결과에 따라 플래그 설정

LODS

Load String

SI 내용을 AL 또는 AX로 로드

STOS

Store String

AL 또는 AX를 ES:DI가 지시하는 메모리에 저장

Control Transfer

CALL

Call

프로시저 호출

JMP

Unconditional Jump

무조건 분기

RET

Return from CALL

CALL로 스택에 PUSH된 주소로 복귀

JE/JZ

Jump on Equal / Zero

결과가 0이면 분기

JL/JNGE

Jump on Less / not Greater or Equal

결과가 작으면 분기 (부호화된 수)

JB/JNAE

Jump on Below / not Above or Equal

결과가 작으면 분기 (부호화 안 된 수)

JBE/JNA

Jump on Below or Equal / not Above

결과가 작거나 같으면 분기 (부호화 안 된 수)

JP/JPE

Jump on Parity / Parity Even

패리티 플레그가 1이면 분기

JO

Jump on Overflow

오버플로가 발생하면 분기

JS

Jump on Sign

부호 플레그가 1이면 분기

JNE/JNZ

Jump on not Equal / not Zero

결과가 0이 아니면 분기

JNL/JGE

Jump on not Less / Greater or Equal

결과가 크거나 같으면 분기 (부호화된 수)

JNLE/JG

Jump on not Less or Equal / Greater

결과가 크면 분기 (부호화된 수)

JNB/JAE

Jump on not Below / Above or Equal

결과가 크거나 같으면 분기 (부호화 안 된 수)

JNBE/JA

Jump on not Below or Equal / Above

결과가 크면 분기 (부호화 안 된 수)

JNP/JPO

Jump on not Parity / Parity odd

패리티 플레그가 0이면 분기

JNO

Jump on not Overflow

오버플로우가 아닌 경우 분기

JNS

Jump on not Sign

부호 플레그가 0이면 분기

LOOP

Loop CX times

CX를 1감소하면서 0이 될 때까지 지정된 라벨로 분기

LOOPZ/LOOPE

Loop while Zero / Equal

제로 플레그가 1이고 CX≠0이면 지정된 라벨로 분기

LOOPNZ/LOOPNE

Loop while not Zero / not Equal

제로 플레그가 0이고 CX≠0이면 지정된 라벨로 분기

JCXZ

Jump on CX Zero

CX가 0이면 분기

INT

Interrupt

인터럽트 실행

INTO

Interrupt on Overflow

오버플로우가 발생하면 인터럽트 실행

IRET

Interrupt Return

인터럽트 복귀 (리턴)

Processor Control

CLC

Clear Carry

캐리 플레그 클리어

CMC

Complement Carry

캐리 플레그를 반전

CLD

Clear Direction

디렉션 플레그를 클리어

CLI

Clear Interrupt

인터럽트 플레그를 클리어

HLT

Halt

정지

LOCK

Bus Lock prefix

STC

Set Carry

캐리 플레그 셋

NOP

No operation

STD

Set Direction

디렉션 플레그 셋

STI

Set Interrupt

인터럽트 인에이블 플레그 셋

WAIT

Wait

프로세서를 일지 정지 상태로 한다

ESC

Escape to External device

이스케이프 명령

2. 8086 어셈블러 지시어(Directive)

지시어

내 용

형 식

SEGMENT

-

END

어셈블리 프로그램은 한 개 이상의 세그먼트들로 구성된다. SEGMENT 지시어는 하나의 세그먼트를 정의한다.

segname SEGMENT ; 세그먼트 시작

⋮ ; 세그먼트 내용

segname ENDS ; 세그먼트 끝

PROC

-

ENDP

매크로 어셈블리에서는 프로그램의 실행 부분을 모듈로 작성할 수 있다. 이 모듈을 프로시저(Procedure)라 부르며, PROC 지시어가 이를 정의한다.

procname PROC ; 프로시저의 시작

⋮ ; 프로시저의 내용

procname ENDP ; 프로시저의 끝

ASSUME

어셈블러에게 세그먼트 레지스터와 사용자가 작성한 세그먼트의 이름을 연결시킨다.

ASSUME SS:stack_segname,

DS:data_segname,

CS:code_segname,

ES:extra_segname

END

전제 프로그램의 끝을 나타냄

END

데이터 정의 지시어 : 프로그램에서 데이터를 저장할 기억 장소를 정의, 초기값 부여

DB

Define Byte

name DB 초기값

DW

Define Word

name DW 초기값

DD

Define Double Word

name DD 초기값

DQ

Define Quad Word

name DQ 초기값

DT

Define Ten Bytes

name DT 초기값

EQU

변수 이름에 데이터값이나 문자열 정의

name EQU 데이터값/문자열

=

EQU와 달리 정의된 값을 변경 가능

EVEN

어셈블리시 이 지시어가 사용되는 곳의 주소가 짝수로 되도록 함

PAGE

어셈블리 리스트의 형식을 결정

PAGE [length][,width]

TITLE

어셈블리 리스트의 각 페이지에 제목 출력

TITLE text

※ 세그먼트(SEGMENT)와 오프셋(OFFSET)

16비트 레지스터를 사용하여 주소를 표현한다면, 216Byte = 65536 Byte = 64 KByte 의 주소 공간을 가질 수 있다. 그러나 지정 가능 주소 공간의 크기를 늘리기 위하여

'세그먼트', '오프셋'의 개념을 사용한다. 개념적으로는 메모리를 가리키는 화살표를

세그먼트(SEGMENT)라고 하고 그곳을 기준으로 떨어진 변위(DISPLACEMENT)를

오프셋(OFFSET)이라고 한다.

8086은 세그먼트를 16바이트 단위로 취하여 그곳으로부터 오프셋 지정으로 주소값을 얻는다.

세그먼트값 × 16 + 오프셋 = 실제주소

16을 곱한다는 것은 왼쪽으로 4번 시프트 한것과 같다. 이 때, 세그먼트 레지스터는

16비트이므로 실제 주소는 16비트를 왼쪽으로 4번 시프트한 20비트의 주소 공간을

가리킬 수 있게된다.

예를 들어, 세그먼트가 A000, 오프셋이 00FF 일 때 실제 주소 값은 다음과 같이 계산할 수 있다.

A

0

0

0

세그먼트

+

0

0

F

F

오프셋

A

0

0

F

F

실제 주소값

이러한 세그먼트, 오프셋에 의한 방식의 장점은 작은 레지스터 크기로도

넓은 주소 공간을 가리킬 수 있다는 것이다.

8086의 경우 20비트의 주소 공간이므로 220Byte = 1048576 Byte = 1 MByte 까지의 주소 공간을 가질 수 있다.

'AssemBly' 카테고리의 다른 글

[AssemBly] 메모리 기초강의  (0) 2020.04.10
[AssemBly] 기초 명령어 소개  (0) 2020.04.10
posted by 핵커 커뮤니티
:
AssemBly 2020. 4. 10. 16:13

Assembly 명령어 소개!

mov,lea 는 데이터이동

 

add, sub, inc, dec 는 논리,연산

 

cmp, jmp 는 흐름제어

 

call, rat 은 프로시저

 

push, pop 는 스텍조작

 

mov = 데이터 이동할때 사용함

 

lea = 주소값을 옮길려고 할때 사용함

 

add = 레디스터나 메모리의 값을 더하기 할때

 

sub = 레지스터나 메모리의 값을 뺄셈할때

 

dec = 값을 1 감소 시킬때

inc = 값을 1 증가 시킬때

 

cmp = 레지스터와 레지스터의 값을 서로 비교할때

 

jmp = 특정한 곳으로 분기 시킬때

 

call = 프로시저를 호출하고싶을때

 

ret = 호출했던 바로 다음 지점으로 이동시킬때

push = 값을 스택에 저장하고싶을때

 

pop = 값을 스텍에 삭제하고 싶을때

'AssemBly' 카테고리의 다른 글

[AssemBly] 메모리 기초강의  (0) 2020.04.10
[AssemBly] 기본적인 명령어 모음  (0) 2020.04.10
posted by 핵커 커뮤니티
: