본문 바로가기

Assembly

3-2강 - 어셈블리어 기본 2 (Assembly Language Fundamentals 2) -

2. Assembling, Linking, and Running Programs 

 

1) Assemble-Link-Execute Cycle 

1> text editor로 source file 생성

2> assembler는 source file을 object file로 변환

- 옵션에 따라 listing file 생성 

3> linker에 object file을 읽고 -> link library 안에 있는 procedure를 호출하는지 점검 후

-> 필요한 procefure는 object file과 합쳐서 executable file을 생성

- 옵션에 따라 map file 생성 

4> loader를 이용해 실행 파일을 메모리로 읽어들이고 프로그램의 실행 결과 값을 도출한다.

 

2) Listing File

1> Listing File : 프로그램이 어떻게 컴파일 되었는지 확인하기 위해 사용 (프로그램 소스 코드 복사본)

2> 포함하는 것 : source code, addresses, object code(machine language), segment name, symbol(variables, procedures, and constants)

3) map file

1> map file : link될 프로그램에 포함된 segment 정보

- starting address, ending address, size, segment type

 

 


 

3. Defining Data 

1) Intrinsic Data Types

           
BYTE 8-bit unsigned integer 0~256 SBYTE 8-bit signed integer -128~127
WORD 16-bit unsigned integer 0~65,335 SWORD 16-bit signed integer -32,668‬~32,667
DWORD 32-bit unsigned integer 0~4,294,967,295 SDWORD 32-bit signed integer  
QWORD 64-bit unsigned integer        
TBYTE 80-bit unsigned integer        
REAL4 4-byte IEEE short real        
REAL8 8-byte IEEE short real        
REAL10 10-byte IEEE extended real        

2) Data Definition Statement

1> 역할

- variable의 공간을 memory에 마련하는 것

- data를 지칭하는 이름(identifier, label)을 붙여도 된다.

2> syntax

[namedirective initializer[,initializer] ...

- 모든 intializer는 memory에 binary data로 들어간다.

 

3) Defining Bytes

1> Defining a single byte of storage

- value6 BYTE ? : unitialized byte (이와 같이 초기화하지 않을 수 있다.)

cf>

MASM은 BYTE 형에 음수 값을 넣는 것을 막지 않지만, 이는 좋지 않은 스타일이라는 것이 정론임

SBYTE형 변수를 선언하면, 마이크로소프트 디버거는 출력시 자동으로 부호를 표시해줌

 

2> Defining multiple bytes of storage with initialization

- 마치 array에 값을 저장하는 것과 같다. 

- list2는 12개의 byte를 가진다. (이와 같이 줄을 바꿔도 list2의 값이다.)

- list3을 보면 각기 다른 값을 저장할 수 있다.

 

4) Defining Strings

1> 큰 따옴표 혹은 작은 따옴표로 enclose

2> null byte를 넣을 수도 있고 아닐 수도 있다.

(str3 BYTE 'A','E','I','O','U' == str3 BYTE 'AEIOU', 0)

3> 하나의 문자열을 여러 줄에 걸쳐 적고 싶다면, 각 줄의 마지막에 콤마(,)를 붙여준다.

4> 개행을 구현하려면 0Dh, 0Ah를 같이 써야 한다.

- 0Dh = carriage return = \r = 커서를 현재 행의 맨 좌측으로 옮기기

- 0Ah = line feed = \n = 커서를 다음 행으로 넘기기

- MS에서는 0Dh와 0Ah를 같이 써야 다음 행에 쓸 수 있다.

 

5) DUP operator

1> 연속된 여러 값들을 한꺼번에 초기화할 수 있게 해주는 연산자

2> format

[namedirective counter DUP(argument)

3> example

var1 BYTE 20 DUP(0)         ; 20 bytes, all equal to zero
var2 BYTE 20 DUP(?)         ; 20 bytes, uninitialized
var3 BYTE 4 DUP("STACK")    ; 20 bytes: "STACKSTACKSTACKSTACK"
var5 BYTE 10, 3 DUP(0), 20  ; 5 bytes

- var5

10 0 0 0 20 => 5byte

 

6) Defining data example

1> Defining WORD and SWORD Data (16 bit)

word1  WORD 65535          ; largest unsigned value
word2  SWORD -32768        ; smallest signed value
word3  WORD ?              ; uninitialized, unsigned
word4  WORD "AB"           ; double characters
muList WORD 1, 2, 3, 4, 5  ; array of words
array  WORD 5 DUP(?)       ; uninitialized array

- muList는 10byte = 5*2byte

- array는 10byte = 5*2byte

 

2> Defining DWORD and SDWORD Data (32 bit)

val1 DWORD 12345678h           ; unsigned
val2 SDWORD -2147483648        ; signed
val3 DWORD 20 DUP(?)           ; unsigned array
val4 SDWORD -3, -2, -1, 0, 1   ; signed array

- val1은 16진수가 8자리이므로 (1자리에 4bit -> ) 8자리면 32bit(4byte) 차지한다.

- val3 : 20*4byte = 80byte

- val4 : 각 숫자가 4byte(SWORD)인 SWORD array

 

3> Defining QWORD, TBYTE, Real Data (나중에 다룰 예정)

quaa1 QWORD 1234567812345678h
val1 TBYTE 1000000000123456789Ah
rVal1 REAL4 -2.1
rVal2 REAL8 3.2E-260
rVal3 REAL10 4.6E+4096
ShortArray REAL4 20 DUP(0.0)

 

7) Little Endian Order

1> 정의

- byte보다 큰 자료들에 대해 (8-bit보다 커야 2자리 이상이 나와서 역순으로 배치를 해볼 수 있다.)

- 각각의 byte(한 자리)를 역순으로 메모리에 저장 

=> LSB(앞자리, 하위 바이트)가 메모리의 가장 처음(Low address)에 저장된다. (LL로 암기하자)

2> 특징

- 컴퓨터 연산에 적합한 방식이다.

- 반대로 저장하는 방식을 Big Endian Order라고 한다.

3> 예시

val DWORD 12345678h

8) Declaring Uninitalized Data

1> 방법

- (data segment에서) .data? 라는 directive 사용

- (data segment 내부) variable 선언할 때 ? 를 initailizer로 사용한다.

2> 장점

- 실행 파일의 크기가 줄어든다.

3> 예시

TITLE Add and Subtract, Version 2
; This program adds and subtracts 32-bit unsigned
; integers and stores the sum in a variable.
INCLUDE Irvine32.inc
.data
val1 DWORD 10000h
val2 DWORD 40000h
val3 DWORD 20000h
finalVal DWORD ?
.code
main PROC
    mov eax, val1      ; start with 10000h
    add, eax, val2     ; add 40000h
    sub eax, val3      ; subtract 20000h
    mov finalVal, eax  ; store the result (30000h)
    call DumpRegs      ; display the registers
    exit
main ENDP
END main

 

 


 

4. Symbolic Constants

cf> Symbol

  symbol variable
저장공간 차지 차지하지 않는다. 차지한다.
runtime 중에 변화 변하지 않는다. 변한다.

symbol은 저장공간을 차지하지 않고 runtime 중에 바뀌지 않는다.

 

1) Equal-Sign Directive

1> format

name = expression

- expression은 32bit 정수이다.

- name은 symbolic constant라고 부른다.

2> 정의 및 특징

- C에서 매크로와 같다.

- redefine 가능

3> 예시

COUNT = 500
.
.
mov ax, COUNT

 

2) EQU Directive

1> format 

symbol EQU value

2> 정의 및 특징

- symbol을 정수나 문자/문자열로 정의

- C에서 매크로와 유사

- redefine이 불가능

3> 예시

PI EQU <3.1416>
pressKey EQU <"Press any key to continue...", 0>
.data
prompt BYTE pressKey

3) TEXTEQU Directive

1> format

symbol TEXTEQU value

2> 정의 및 특징

- EQU와 유사하다.

- 재정의 가능하다. (EQU와 달리 재정의 가능)

- text macro라고 불린다.

- %(constant expression)이 가능하다. (EQU는 사용 불가능)

3> 예시

continueMsg TEXTEQU <"Do you wish to continue (Y/N)?">
rowSize = 5
.data
prompt1 BYTE continueMsg
count TEXTEQU % (rowSize * 2)     ; evaluate the expression ; %는 계산하라는 뜻이다/
setupAL TEXTEQU <move al, count>  ; 일단 TEXTEQU로 치환해두고 2줄 밑에서 실행한다. ("mov al, 10" 이라는 뜻이다.)
.code
setupAL                           ; generates: "mov al, 10"

- % : constant expression (계산하라는 뜻이다.)

 

4) Current Location Counter

1> $는 현재 위치(메모리 주소)를 나타낸다.

(어셈블리는 계속해서 location을 count하고 있다.)

2> BYTE 예시

list BYTE 10, 20, 30, 40
ListSize = ($ - list)

- list(주소)에는 10 / list+1에는 20 / list+2에는 30 / list+3에는 40 할당하고

- $는 list+4를 나타내고 있다.

그래서 ListSize=4라는 결과가 나온다. 

 

3> WORD 예시

- BYTE와 달리 WORD는 메모리를 2byte씩 쓰기 때문에

- $(현재 주소)-list(시작 주소) 를 2로 나누어 주어야 ListSize를 구할 수 있다.

list WORD = 1000h, 2000h, 3000h, 4000h
ListSize = ($ - list) / 2

4> DWORD 예시

- DWORD도 마찬가지의 논리로 4를 나눈다.

list DWORD 1, 2, 3, 4
ListSize = ($ - list) / 4

 

 

cf> 16-bit MS-DOS programming

1) 16-bit MS-DOS programming을 사용하려면

1> 라이브러리 include

INCLUDE Irvine16.inc 

2> main function 안에 intialize

Initialize DS to the data segment:
mov ax,@data
mov ds,ax