segment .data

string  db      'hello,world!!!',10,00


#>cat hello2.asm

segment .text

global _start

_start:

mov eax, 4

mov ebx, 1

mov ecx, string

mov edx, 16

int 0x80





어셈블리로 컴파일한 hello2 elf 헤더 내용을 살펴보면 


#>objdump -x hello2

hello2:     file format elf32-i386

hello2

architecture: i386, flags 0x00000112:

EXEC_P, HAS_SYMS, D_PAGED

start address 0x08048080//실행파일이 메모리에 올라가면 가상 메모리에서 시작 위치를 나타낸다.처음 어느정도의 메모리는 사용하지 않는다(메모리상의 주소)


Program Header:

    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12

         filesz 0x00000096 memsz 0x00000096 flags r-x   0804800부터 150바이트를 차지한다 총 2의 12승 4K의 공간을 차지하는데 150바이트 빼고는 나머지는 패딩으로 채워진다 (flags r-x 권한을 보면 여기가 text인걸 알수있다.)


    LOAD off    0x00000098 vaddr 0x08049098 paddr 0x08049098 align 2**12 파일상에서 옵셋은 98 가상에서는 9098이다. 위의 4800 보다 4K 떨어져 있는 위치에 존재한다. 기본 정렬 단위는 4K  (flags rw- 권한을 보면 읽고 쓸수 있다) 

         filesz 0x00000010 memsz 0x00000010 flags rw-  일 크기는 hello world 만큼의 크기이다. 이 크기를 제외한 4k에서 남는부분은 패딩 된다 


Sections:

Idx Name          Size      VMA       LMA       File off  Algn

  0 .text         00000016  08048080  08048080  00000080  2**4

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

  1 .data         00000010  08049098  08049098  00000098  2**2

                  CONTENTS, ALLOC, LOAD, DATA

  2 .bss          00000000  080490a8  080490a8  000000a8  2**0

                  CONTENTS

  3 .comment      0000001f  00000000  00000000  000000a8  2**0

                  CONTENTS, READONLY



실행파일을 분석할줄 알아야한다 

위의 heade 내용을 찾아보면


여기 까지가 헤더 내용인걸 알수있다.

LOAD off    0x00000098 vaddr 0x08049098 paddr 0x08049098 align 2**12 

9098을 확인해보면 90에서 8번 까지가 헤더 내용이다


여기는 hello 를 표현 하는 부분이다.



이런식으로 바이너리와 어셈블리를 하나하나 비교하면 확인이 가능하다




초기화 데이터의 차이 


char str[]="Hello,World!!";<- 초기화된 데이터 크기를 알아야한다

char str[];<-초기화가 안된 데이터


여기서 data와 bss 의 차이가 나온다 


2. DATA 섹션 ( 세그먼트 )  // 문자열 데이터 출력 

- 읽기/쓰기 가능한 메모리 영역 

- 프로그램 실행에 필요한 데이터  

- 실행 권한이 없다

segment .data

string  db      'hello,world!!!',10,00



3. BSS 섹션( 세그먼트 )

- 읽기/쓰기 가능한 메모리 영역 

- 초기화 되지 않은 데이터 영역 


저번시간에 배운 DATA 섹션은 초기화가 된 데이터가 들어가고 BSS 섹션은 초기화 되지 않은 데이터 영역이 들어간다



NASM 문법은 홈페이지 에서 참조가 가능하다



C언어

1.)데이터 타입

-숫자(정수,실수),문자,문자열




nasm 숫자를 표현하는 방법 





10진수

1.아무 숫자 없이 사용

2.d를 붙여서 사용


16진수

1.h를 붙여서 사용 

2.앞에 Ox 붙여서 사용


8진수

1.q를 붙여서 사용

2.o를 붙여서 사용


2진수 

1.b를 붙여서 사용




nasm 문자 표현 하는 방법


segment .data

string  db      'hello,world!!!',10,00  //여기서 10은 new line을 표현해준다,문자열은 null로 끝나야해서 00을 추가해야한다


열거형으로 사용이 가능하다

string  db      'h','e','l','l','o',10,00


기본 구조

label:    instruction operands        ; comment



2.)레이블 Vs. 변수


1).변수

-값,주소,크기

-int var = 10;


2).레이블은 주소 대신에 이름표를 붙인다는 의미

    주소를 매번 계산하기가 어렵기 때문에 주소를 나타내는 이름표를 사용한다. 

    쓰는건 문자열을 쓰지만 실제로는 주소를 쓴다


변수와 레이블은 전혀 다른 개념이다.


entry point

segment .text

global _start

_start: //명령어의 시작 위치 

mov eax, 4

mov ebx, 1

mov ecx, string

mov edx, 16

int 0x80


_start 는 entry point 이다.



extern printf

segment .data

string  db      'hello,world!!!',10,00

segment .text

global main


main:

        push string

        call printf


gcc를 쓰는 경우에는  entry point가 main이 되어야 한다.


그래서 레이블을 중복해서 사용할수 없다 

extern printf

segment .data

string  db      'hello,world!!!',10,00

string  db      'hello!!!',10,00

//이런식으로 사용이 불가능하고 

string2  db      'hello!!!',10,00

//이렇게 사용해야한다 

레이블 이름을 붙이는건 변수이름 지정하는거랑 비슷하다




segment .text

global main


main:

        push string

        call printf



3.데이터의 크기

1).접두사: d, res

데이터에다가 쓰는경우는 d, bss에 사용하는 경우는 res를 사용한다



2).단위

byte unit C

1 (b)yte char

2 (w)ord short

4 (d)word int, float, pointer, ...

8 (q)word long long,double..

10 (t)enbyte


db,dw,dd,dq,dt 이렇게 사용이 가능하다


C언어로 표현하면 

string  db      'hello,world!!!',10,00    ;char string[]="hello, world\n"


BSS 섹션( 세그먼트 )

- 읽기/쓰기 가능한 메모리 영역 

- 초기화 되지 않은 데이터 영역 

segment .bss

buffer resb 1024 ;char buffer[1024];


ex) int apple =10;

segment .data

apple dd 10


ex) int orange;

segment .bss

buffer resd 1


명령어


main:

        ;printf("hello, world!!!\n")

        push string //인자의 개수와 push 의 개수는 일치해야한다. string(주소)만 입력을 해주면 된다.

        call printf //printf 를 호출


        ;printf("num of apple: %d\n",apple)

        push dword [apple]

        push prompt

        call print

        

        인자가 여러개인 경우에는 뒤에서 부터 수행하면된다 push,push,call

        사용할 함수는 extern을 꼭 해야한다



실습


(0)_(0)(0)_(0)

(=^.^=)(*^.^*)

(_m_m)(_m_m_)

만들기 


extern printf

segment .data

string1 db     '%s%s%s',10,00

string2 db     '(0)_(0)(0)_(0)',10,00

string3 db     '(=^.^=)(*^.^*)',10,00

string4 db     '(_m_m)(_m_m_)',10,00

segment .text

global main


main:

        push string4

        push string3

        push string2

        push string1

        call printf



역순으로 PUSH후 CALL을 해주어야 한다



















+ Recent posts