본문 바로가기

교육/ASSEM

어셈블리어 기초



instruction 
  • 명령어

.NOLIST 
  • 앞에 마침표가 들어가 있으면 directive 라 한다. 디렉티브와 인스트럭션이 모이면 스테이먼트라고 한다.

name mnemonic operand(s) ;comment

ZeroCount : mov ecx, 0 ; initialize count to zero
  • mnemonic - 니모닉이라 발음 (m 은 묵음)
  • ; (세미콜론) 뒤는 주석
jmp addLoop ; repeat addition
  • name이 없는 경우
EndIfBlank:
  • name만 있는 경우




.386
  • 사용하고 싶은 기능이 어셈블리 버전을 초과한 경우에 써준다. (CPU)
  • .486, .586 은 .386이상의 기능을 사용하게 해 준다. (.586을 사용하면 .586이하의 시스템에는 사용되지 않는다.)
.MODEL FLAT
  • flat모드를 사용하고 싶을 때 어셈블리 코드의 제일 첫번 째에 작성해 주어야 한다. 
  • 세그먼트와 반대이다.



ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
  • exit함수 선언
  • 공간을 확장하기전의 셋팅을 저장해 두었던 원래의 상태로 돌아가는 함수 (초기화, Reset함수)
  • INCLUDE io.h
INCLUDE io.h
  • include를 #없이 한다. (어셈블러에 따라 다르다.)
  • 교육용으로 만들어진 헤더파일



 
 .386           //.389 이하 기능사용

 .MODEL FLAT   //FLAT모드 사용한다.

 ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD  //Exit함수 선언

 INCLUDE io.h  //#include 교육용 헤더파일

 cr EQU 0dh    //#define cr 0dh
               //EQU은 이퀄(=)
               //0ch에서 뒤에붙은 h는 16진수를 뜻한다.

 Lf EQU 0ah

 .STACK 4096  //스택 4kb


/* -------------------------------------------- */
/*    데이터영역, 이 밑으로는 전역변수        */


 .DATA 

//DWORD = 4byte, ? = 쓰레기값 C언어 식으로 선언하면 DWORD number1 = ?;
//어셈블러는 전역변수의 초기값이 정해지지 않는다.
     number1 DWORD ?  //변수이름 자료형 값

     number2 DWORD ?

//BYTE = 1byte, " " 배열과 비슷하게 동작 1byte씩 메모리를 할당
//C언어처럼 배열의 끝에 NULL을 넣어주지 않기 때문에 ,(콤마)뒤에 0을 넣어준다.
     prompt1 BYTE "Enter first number: "0    

     prompt2 BYTE "Enter second number: "0

//(40 DUP (?) - 물음표를 40개 복사한다는 의미), DUP = 오른쪽의 값을 복사
//만약 자료형이 DWORD면 40개가 아닌 160개가 들어감 (4배)
     string BYTE 40 DUP (?)            

//cr , Lf, T, h, e, , s, u, m, , i, s 순으로 차례대로 메모리 할당
//(끝에 Null을 채워주지않았음)
     label1 BYTE cr, Lf, "The sum is "      

     sum BYTE 11 DUP (?)

//이름이 지정되지않은 변수가 메모리만 차지하는 중임. (Enter 역할)
     BYTE cr, Lf, 0                

/* -------------------------------------------- */
/* -------------------------------------------- */



/* -------------------------------------------- */
/*    데이터영역, 이 밑으로는 지역변수        */


 .CODE 

//함수이름 (C에서 호출할 수 있도록 하기 위해 함수이름 앞에 _(언더바)를 붙여줌)
//언더바를 안 붙여준 함수의 경우 어셈블리어 끼리만 호출하도록 하는 의미
 _start:          

// output이라는 매크로 시작  (주소를 적으면 그 주소의 값을 출력)
// prompt1의 값 출력 - "Enter first number : ", 0  (printf와 같음)
     output prompt1 

// 40개의 문자를 키보드로 입력받아서 출력 (scanf와 같음)
     input string, 40 

// 문자를 int형으로 바꾸는 책제작자가 만든 함수형
     atod string

// eax의 값을 number1 으로 mov(대입)
// - intel은 메모리는 리틀엔디안인데 레지스터는 빅엔디안임
     mov number1, eax

     output prompt2

     input string, 40

     atod string

     mov number2, eax

     mov eax, number1

// eax = eax + number2
     add eax, number2

// int형을 ASCII코드형으로 바꾸는 책제작자가 만든 함수
     dtoa sum, eax 

     output label1

// 메모리와 레지스터 셋팅을 초기화한다. (원상태로 돌려놓고 종료시킨다.)
     INVOKE ExitProcess, 0 


/* -------------------------------------------- */
/* -------------------------------------------- */


// _start 함수를 PUBLITC을 적어서 C에서 접근할 수 있도록 하는 명령어.
 PUBLIC _start 

 
END




  • 비주얼스튜디오는 스택의 초기값을 모두 C로 채워넣는다.


ASM 컴파일 방법
  • ml /c /coff example.asm

ASM 링크 방법
  • link /subsystem:console /entry:start /out:example.exe example.obj io.obj kernel32.lib



ASM 디버거 컴파일 방법
  • ml /c /coff /Zi example.asm

ASM 디버거 링크 방법
  • link /debug /subsystem:console /entry:start /out:example.exe example.obj io.obj kernel32.lib

- 디버거 컴파일과 링크를 했을 경우에
  • DOS창에서 Windbg를 써서 디버거를 사용하라 [Start the debugger by typing Windbg at the DOS prompt.] 






Windbg를 사용하면 나오는 화면