'어셈블리(MASM)'에 해당되는 글 5건

; 자료형의 크기
DB           ; "Data Byte"의 약어로 1Byte
DW           ; "Data Word"의 약어로 2Byte
DD           ; "Data Double-Word"의 약어로 4Byte


CYLS EQU 10 ; #define CYLS  10

; 패딩
RESB 10   ; "Reserve Byte"의 약어로 10바이트를 띄워놓는다 (0x00)
RESB 0x1FE - $                    ; $는 선두로부터 몇바이트 떨어져이는지



; 명령어
ORG 0x7c00   ; 실행시에 PC의 메모리내의 어디에 로딩되는지 ($를 좌우)


MOV AX,0                            ; AX = 0
MOV BYTE[678], 123   ; BYTE[]캐스팅, '데이터크기[주소]'

ADD SI, 1                            ; SI += 1
CMP AL, 0                           ; AL과 0의 비교

HLT                                             ; CPU정지명령

 
 JUMP명령
entry:                         ; 레이블 선언

JUMP entry          ; Goto명령, 레이블로 무조건 점프
JE                             ; CMP의 비교결과가 같으면 점프
JC                             ; Carry플래그가 1이면 점프(자리올림)
JNC                           ; Carry플래그가 0이면 점프

JAC                           ; 크거나 같으면 점프
JBE                           ; 작거나 같으면 점프
JB                             ; 작으면 점프
Posted by 응이

.386
.MODEL FLAT

;함수 사용  선언(ExitProcess 함수이름 이며 반환형은 DWORD)
ExitProcess PROTO NEAR32 stdcall, dxExitCode:DWORD

;헤더파일 인클루드
INCLUDE io.h

cr EQU 0dh         ;0dh => 0x0d (h 는 16진수를 나타낸다.)#define 효과
Lf EQU 0ah         ; EQU는 (=) 과 같다

.STACK 4096        ;스택영역을 4096만큼 확보(사용할 메모리 공간 확보)

.DATA          ;변수 영역 시작
number1  DWORD ?       ;4바이트로 변수 선언
number2  DWORD ?
prompt1   BYTE "Enter first number: ",0  ;문자를 바이트 단위로 할당하고 마지막에 0을 넣는다.
                                                         0은 문자열로 넣지 않고 (,0) 을 사용

prompt2  BYTE "Enter second number: ",0
string     BYTE 40 DUP (?)                ;BYTE 단위를 40개를 DUP(할당) 한다. (?) 는 초기화
                                                      하지 않는다는 말
label1    BYTE cr, Lf, "The Sum is "  ;cr Lf 는 위에서 정의 한 값인 16진수를 사용(\n\r)효과
sum       BYTE 11 DUP (?)
             BYTE cr, Lf, 0                    ;변수명 없이 메모리만 할당(sum뒤에 이어서 cr과Lf
                                                      그리고 0이 오게된다.

.CODE                                      ;코드영역의 시작
_start:                                       ;start함수 (시작 지점을 의미)
   output prompt1                        ;output 은 메크로함수로 화면에 출력을 하는 메크로다.
   input string,40                         ;input은 입력을 받는 메크로다. 40바이트 만큼
   atod string                              ;atod는 아스키 코드를 10진수로 변환 하는 메크로다.
                                                (DWORD형으로저장후 레지스터eax에 넣어준다.)
   mov  number1,eax                    ;eax의 내용을 number1에 넣어준다. mov는 복사해주는
                                                역할을 한다.
   
   output prompt2
   input string,40
   atod string                              ;위에서 연산된 값은 지워지고 새로운 값이 eax에 저장된다.
   mov  number2,eax
   
   mov  eax,number1    
   add  eax,number2                    ;뒤에값을 앞에 값과 더해 앞에 공간에 넣어준다.
                                                 (a = a+ b 와 같다.)
   dtoa sum,eax                          ;eax에 있는 숫자를아스키 코드로 바꿔준다.(sum에 아스키
                                                 로  바꾼 값을 담아준다.)
   output label1                           ;label1 BYTE cr, Lf, "The Sum is " 으로 정의 되어 있는
                                                곳에 널문자가 없어
                                                ;다음에 있는 sum부분의 널을 만날때까지 계속 출력한다.
   INVOKE ExitProcess,0              ;INVOKE는 함수를 호출하라는 명령어 함수명은
                                                ExitProcess며 인자는 0이다.
   
PUBLIC _start                             ;PUBLIC 을 사용해서 외부로 부터의 접근을 허용한다.

END                                          ;프로그램 종료를 알리는 부분


위에서 사용된 input output 과 atod , dtoa 등은 메크로로 화면에 출력 ,입력받기,아스키를 10진수로 변환, 10진수를 아스키로 변환 하는등의 역할을 한다.  어셈블리어 코드가 아니며 따로 정의되어 있는 오브젝트 파일을 링킹시켜야 사용 가능하다.

Posted by 응이

prefix byte 란?

어셈블리(MASM) 2008. 11. 26. 16:28

prefix byte 란?

mov  ax , 0

mov   eax , 0

은 둘다 같은 opcode(기계어 코드)인 B8을 가리키지만 ax 레지스터는 16비트, eax레지스터는 32비트 레지스터이다 따라서 뒤에 오는 어퍼렌드는 크기가 달라서   mov ax,0은 B8 00 00  처럼 기계어로 대치되며 mov eax,0은 B8 00 00 00 00 처럼 기계어로 대치된다. 이와 같이 오퍼렌드의 크기는다른데 opcode가 같다면 이것을 구분하기 위해 prefix byte를 사용하게 되는데 66 B8 00 00 처럼 16비트 오퍼렌드를 가지는 opcode 앞에 0x66 을 붙여 뒤에오는 오퍼렌드가 16비트 임을 알린다

사용자 삽입 이미지



그림에서 보는것과 같이 mov ax,0 과 mov eax,0을 코드로 작성하고  디버깅을 한후 값을 확인 해보면

메모리에 prefix byte 인 0x66이 들어 있는 것을 확인 할수 있다.




Posted by 응이

레지스터란

CPU 내부에 있는 8,16,32Bit 고속 저장소를 말하며 일반적으로 사용하고 있는 메모리 보다 데이터를 훨씬 빨리 읽거나 쓰도록 되어 있습니다.

종류로는

세그먼트레지스터

CS(Code Segment):프로그램의 실행 명령어들이 내장되는 메모리 영역의 시작위치를 보관합니다.

DS(Data Segment):데이터가 재장되는 메모리 영역의 시작위치를 보관합니다.

SS(Stack Segment):스택으로 사용되는 메모리 영역의 시작위치를 보관합니다.

ES(Extra Segment):변수들을 위한 추가 메모리 영역의 시작위치를 보관합니다.

인덱스 레지스터:데이터와 명령어들의 오프셋 주소를 갖는다.

BP(Base Pointer):SS 레지스터로부터의 오프셋 주소를 갖는다.

SP(Stack Pointer):스택 최상부 위치의 오프셋 주소를 갖는다.

SI(Source Index):소스 문자열이 사용되며 SI레지스터가 이 문자영을 가리킨다.

DI(Destination Index):DI 레지스터는 문자열 이동 명령어에서 데스티네이션을 가리키느데 사용된다.

상태 및 제어 레지스터

IP(Instroduction Pointer):항상 현재 코드 세그먼트내의 다음 실행될 명령어의 오프셋 주소를 갖는다. IP와 CS 레지스터는 결합하여 다음 실행될 명령어의 메모리 주소를 결정한다.

Flag:플레그 레지스터의 비트들은 CPU의 현재 상태 또는 연산 결과와 관련된 정보를 보여 준다. 관련된 비트 위치는 각각 이름이 주어지고, 관련되지 않는 위치들은 정의 되지 않는다.

제어 플래그

방향 플레그(DF):MOVS,CMPS,SCAS같은 명령어들의 블록데이터 이동에 영향을 준자.

 0:데이터 이동 주소 증가, 1:감소

인터럽트 플레그(IF) :시스템 인터럽트들이 처리되거나 되지 않도록 명령한다.

트랩 플레그(TF):명령어 하나 하나 실행된 후 CPU가 정지 상태로 되어야 할지 말지를 결정한다.

상태 플래그:상태 플레그들은 CPU가 실행한 산술 및 논리 연산의 결과를 반영한다.

캐리 플레그 (CF):부호 없는 산술 연산 결과가 너무 커서 데스티네이션 피연산자에 저장되지 못할 때 설정된다.

오버 플로우 플레그(OF): 부호 있는 산술연산 결과가 너무 많은 비트들을 요구하여 데스티네이션 피연자에 저장하지 못할 때 사용된다.

부호플래그(SF):산술 및 논리 연산의 결과가 음의 수가 될 때 설정된다.

보조플래그(ZF):산술 및 논리 연산 결과가 0 일 때 설정된다.

제어플래그(AF):피연산자의 비트 3에서 비트4로 자리올림이 발생했거나, 비트 4에서 비트 3으로 자리내림일 때 설정된다.

패리티플래그(PF):연산 결과에서 값이 1인 비트이 수를 나타낸다


Posted by 응이

- 함수의 정의

함수가 정의된 파일이 아닌 외부 파일에서 함수사용을 가능 하게 하기위해 함수를 PUBLIC으로
선언해 주어야 한다.

PUBLIC TEST

PUBLIC TEST,TEST2,TEST3 처럼 여러개의 함수를 ( , ) 를 사용해서 같이 적을 수 있다.



== 어셈블리 == 

TEST PROC NEAR32

push ebp           

mov ebp,esp

 함수 내용부


mov esp,ebp

pop ebp

ret

TEST ENDP
 



== C 언어 ==

void TEST(void)

{

 함수 내용부

}


 

위에서 어셈블리 함수 에서 볼수 있는

push ebp           

mov ebp,esp

는 함수의 Entry Code라 하고 함수 시작부 주소의 설정과 호출되기전 함수의 시작부 등을 설정해 주는 기능을 한다. 함수내에서 반드시 있어야 할 코드이다.

Entry Code와 함께 있어야할것이 바로 Exit Code라 불리는 아래 코드다.

mov esp,ebp

pop ebp

ret

Entry Code와 함께 반드시 있어야 하며 Entry Code에서 변경 되었던 EBP(Entry Base Point)를
다시 호출되기전 값으로 복구시키고 리턴어드레스로 돌아가게 하는 역할을 한다.

 - 함수의 선언

어셈블리 역시 C언어나 기타 언어처럼 함수의 선언이 가능하다.

어셈블리       :      EXTERN TEST:NEAR32

C 언어         :      void TEST (void)



 

- 함수 호출시의 STACK 구조

인자 없이 사용되는 함수의 호출시 메모리 STACK 구조는 다음과 같다.

                 

                   -  호출전 -

사용자 삽입 이미지

     

           -  호출 직후  -

사용자 삽입 이미지


                 -   호출시 함수 내부   -

사용자 삽입 이미지


인자가 있는 함수를 사용할 경우의 STACK 구조는 다음과 같다.

사용자 삽입 이미지


   - 함수 내부에서의 인자 접근 방식

 

사용자 삽입 이미지

Posted by 응이
1

Dream come true.
응이

달력

태그목록