본격적으로 어셈블리언어를 배워보자:)

dqQQQ

·

2023. 11. 26. 19:46

개요

3장 : 어셈블리 언어의 기본 구성요소, 데이터 정의를 어떻게 하는지 살펴보겠다.




어셈블리 언어의 기본 구성 요소


{} 는 구성요소중 하나를 선택하라는 의미이다. []안의 내용은 선택사항이라는 의미이다. 이는 MS에서 사용하는 구문 표기법이다.

정수 상수

  • 정의 : 부호와 한자리 이상의 숫자로 구성된 정수 리터럴
  • 기본형식 : + or - digits radix
  • 예시: 26 -> +26d


정수 수식

  • 정의 : 정수 값 + 산술 연산자로 이루어진 식
  • 기본형식 : 정수 값 + 산술 연산자
  • 예시: 4 + 5


실수 상수

  • 정의 : 부호, 정수 , 소수점으로 구성되어있는 10진 실수
  • 기본형식 : [sign]integer.[integer][exponent]
  • 예시: +3.0 // 26.E5


문자 상수

  • 정의 : 2진 아스키코드로 메모리에 저장되는 한 문자
  • 기본형식 : 작은 따옴표 또는 큰 따옴표로 둘러싸인 한 문자
  • 예시: 'a' // "d"


문자열 상수

  • 정의 : 2진 아스키코드로 메모리에 저장되는 문자들의 나열
  • 기본형식 : 따옴표로 둘러싸인 문자열
  • 예시: 'ABC' // "hello"


예약어

  • 정의 : MASM에서 특정 목적이 있는 단어
  • 기본형식 : 예약어별 상이
  • 예시: 명령어, 레지스터 이름, 디렉티브, 속성, 연산자


식별자

  • 정의 : 변수, 상수, 프로시저, 코드 레이블에 사용되는 이름
  • 기본형식 : 프로그래머가 선택한 이름
  • 예시: 예약어를 제외한 본인이 생각한 이름


디렉티브

  • 정의 : 메모리 세그먼트에 이름을 부여하고 어셈블러와 관련된 작업들을 처리하는 명령
  • 기본형식 : 어셈블러가 인식하여 그것에 따라서 동작하는 명령
  • 예시: .data // .code // .stack 100h


명령어

  • 정의 : 프로그램이 어셈블되었을 때에 실행 가능하게 되는 문장
  • 기본형식 : 레이블, 명령어 니모닉, 피연산자, 주석
  • 예시: [label:] mnemonic [operands] [;comment]


레이블

  • 정의 : 명령어 또는 데이터의 위치를 표시하는 식별자
  • 기본형식 : 데이터 레이블(변수의 위치 레이블) / 코드 레이블(분기나 루프 레이블)
  • 예시: count DWORD 100 / target: mov ax, bx ... jmp target


명령어 니모닉

  • 정의 : 명령어를 식별하기 위한 짧은 단어
  • 기본형식 : 특정 단어
  • 예시: mov, add, sub ...


피연산자

  • 정의 : 명령어에 따라 수정되어지는 대상
  • 기본형식 : [명령어 니모닉] [destination] [source] ...
  • 예시: mov count, ebx (move ebx to count)

피연산자 형식은 어셈블러마다 상이하므로 반드시 확인후에 사용



주석

  • 정의 : 프로그램 작성자가 소스코드를 읽는 사람에게 설계에 대한 정보를 제공하는 문장
  • 기본형식 : 한 줄 주석 / 블록 주석
  • 예시: ;hello / COMMENT ! hello !


NOP 명령어

  • 정의 : 1바이트의 프로그램 저장공간을 차지하며 아무런 동작도 하지 않는 명령어
  • 기본형식 : nop
  • 예시: nop

코드와 데이터를 4의 배수로 정렬된 더블워드 주소에서 더 빠르게 적재할 수 있기 때문에 더블워드의 경계에 정렬시키기 위해 사용한다.




프로그램 어셈블, 링크, 실행하기


  • 단계 1 : 프로그래머소스파일을 만든다.
  • 단계 2 : 어셈블러는 해당 소스파일에 대한 오브젝트 파일을 만든다.
  • 단계 3 : 링커는 오브젝트 파일들을 합쳐서 실행 파일을 만든다.
  • 단계 4 : 운영체제의 로더는 실행 파일을 메모리로 읽어들이고 프로그램을 실행한다.

2단계에서 선택사항으로 어셈블러는 리스트 파일을 만든다.

리스트 파일이란 줄번호, 오프셋 주소 , 기계어 코드, 심볼 테이블이 있는 인쇄하기에 적합한 형태의 소스코드의 복사본을 의미한다.


데이터 정의


  • 데이터 정의문(data definition statement)은 메모리에 변수를 위한 저장 공간을 확보한다.

    각각의 데이터 정의 문은 자료형에 근거하여 변수를 생성한다.

    다음과 같은 구문을 가진다. [name] directive initializer [initializer]

  • 데이터 정의에서는 초기값 설정이 무조건 필요하다.

    만약 변수를 초기화하지 않기를 원한다면 ? 기호를 초기값으로 사용하면된다.

  • 여러개로 초기화를 시키고 싶다면 [name] directive initializer [initializer] [,initializer] [,initializer] ...

    예를 들어 list BYTE 10, 20, 30, 40 라면 list는 바이트 배열이며 1바이트의 주소단위로 10, 20, 30, 40이라는 값이 들어있다.

  • 문자열 정의를 위해서는 따옴표 안에 문자열을 넣어야한다. 여기서 중요한 점은 마지막 1바이트는 비워놔야하는데 문자열의 종료를 알려주는 널바이트를 위해서이다.
  • 상수 수식을 반복적으로 사용하여 여러 개의 데이터를 위한 저장 공간을 할당하려면 DUP 연산자를 사용하면된다.

    BYTE 4 DUP ("stack") 라면 20바이트의 공간에 "stackstackstackstack"이 초기화된다.

BYTE와 SBYTE 데이터 정의

BYTE와 SBYTE는 각각 부호없는, 부호있는 8비트의 저장공간을 할당한다.

각각의 값이 1바이트를 차지하므로 주소는 1씩 증가한다.



WORD와 SWORD 데이터 정의

WORD와 SWORD는 각각 부호없는, 부호있는 16비트의 저장공간을 할당한다.

각각의 값이 1바이트를 차지하므로 주소는 2씩 증가한다.



DWORD와 SDWORD 데이터 정의

DWORD와 SDWORD는 각각 부호없는, 부호있는 32비트의 저장공간을 할당한다.

각각의 값이 1바이트를 차지하므로 주소는 4씩 증가한다.



QWORD와 데이터 정의

QWORD는 64비트의 저장공간을 할당한다.

각각의 값이 1바이트를 차지하므로 주소는 8씩 증가한다.



TBYTE 데이터 정의

압축 이진부호화 십진수(BCD(binary coded decimal))란 10바이트의 저장 장소에 바이트 단위로 십진수 두자리를 저장되는 정수를 말한다.

10바이트중에서 맨 처음 바이트는 부호를 나타내는데에 사용된다. 00h라면 양수이고 80h라면 음수를 가리킨다.

압축 BCD를 선언하기 위해서 TBYTE 디렉티브를 사용하는데 초기값은 16진수로 되어있어야한다.

예를 들면 VAL TBYTE 80 00 00 00 00 00 00 00 12 34h와 같이 선언해한다는 것이다. -1234로 선언하면 안된다.

만약 정수가 아닌 실수를 압축 BCD로 부호화한다면 다음의 과정을 따르면된다.

  • 1단계 : FLD(floating point load)명령어를 사용하여 부동 소수점 레지스터 스택에 적재
  • 2단계 : FBSTP(BCD store and pop)명령어를 사용하여 압축 BCD로 변환

실수 데이터 정의


리틀엔디언 순서


x86 프로세서들은 기본적으로 리틀엔디언 순서를 이용하여 메모리에 데이터를 저장하고 꺼낸다.

12345678h를 저장한다면

  • 리틀엔디언
  • 빅엔디언

기호 상수


기호 상수란 기호를 정수 수식또는 텍스트와 연관시킨 상수를 의미한다.

C언어의 #define을 사용하여 만든 상수를 생각하면된다.

기호상수는 별도의 메모리 공간을 차지하지 않고 실행시간에는 변경이 불가능하다.

현재위치 카운터

$를 사용하면 현재위치로 변수를 초기화 시킨다.

예를 들면 selfPTR DWORD $구문은 selfPTR이라는 변수를 선언하고 현재 주소값으로 초기화한다.

명시적으로 배열의 크기를 말하는 것은 오류를 만들 수 있는데 현재위치 카운터를 이용하여 배열의 크기를 구할 수 있다.

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

와 같은 구문이 있다면 4개의 배열의 크기를 가진다고 계산할 수 있다.

만약 WORD배열이라면 2로 나누어주어야한다.

DWORD는 4로 나눈다.

등호 디렉티브

등호 디렉티브는 기호 이름을 정수수식과 연관되게 한다.

예를들면 count = 500이라고 하면 500이라는 값을 사용하고 싶을 때 count를 사용하면 된다.

언제든지 다시 정의될 수 있다.

EQU 디렉티브

EQU 디렉티브는 기호를 정수 수식이나 임의의 텍스트와 연관시킨다.

=와 같은 역할을 한다.

TEXTEQU 디렉티브

텍스트 매크로를 만드는데는 TEXTEQU를 사용하면된다. 3가지의 형식이 있는데 다음과 같다.

  • [name] [TEXTEQU] <text> : 텍스트 매크로 생성
  • [name] [TEXTEQU] textmacro : 텍스트 매크로 내용을 지정
  • [name] [TEXTEQU] %constExpr : 상수 정수 수식

예를 들면

rowsize = 5
count TEXTEQU %(rowsize * 2) ;count라는 상수 정수 수식의 결과값을 텍스트 매크로로 만든다.
move TEXTEQU <mov> ; mov라는 텍스트를 move라는 텍스트 매크로로 만든다.
setupAL TEXTEQU <move al , count> ; 위에서 만들었던 텍스트 매크로를 이용하여 내용을 지정한다.

3줄 요약


  1. C언어와 굉장히 유사하다.
  2. 자료형의 종류가 굉장히 다양하다.
  3. 고수준에서는 자동으로 자료형을 설정해주는 기능이 있지만 저수준에서는 이런것들을 다 직접해줘야하니 어려운것같다.