태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

티스토리 툴바



1.3 데이터 저장소

- 기계어 프로그램에서 데이터가 저장되는 위치

  메모리(memory)
  레지스터(register)
  명령코드 내(instruction operand)
  기타

1.3.1 메모리(memory)

- 초기화된 데이터

segment .data
hello   db  "hello, world", 10, 0       ; char hello[] = "hello, world!n";
number  dd  1, 2, 3, 4                  ; int  number[4] = { 1, 2, 3, 4 };
pi      dq  3.141592                    ; double pi = 3.141592

ones    times 5  dd 1                   ; int twos[5] = { 1, 1, 1, 1, 1 };
stars   times 10 db '*'                 ; char starts[10] = "**********";

- 초기화되지 않은 데이터

segment .bss
buffer  resb 100                        ; char buffer[100];
size    resw 1                          ; short int size;
array   resd 30                         ; long arrary[30];


- 명령 코드에서 데이터 접근

segment .text
        mov  eax, hello                 ; char *eax = &hello
        mov  ebx, [number]              ; int ebx = number[0];
        mov  [array + 8], eax           ; array[2] = eax;


1.3.2 레지스터(register)

- 레지스터: CPU 내에 있는 고속 기억소자
  
- 레지스터 크기: 8, 16, 32, 64 bit

- 레지스터에 데이터를 저장하는 명령 코드 예
  mov ah,  1      ; ah = 1
  mov eax, ebx    ; eax = ebx
  add eax, 2      ; eax = eax + 2

- 레지스터는 읽기/쓰기 속도가 다른 메모리보다 빠르므로
  가능하면 데이터를 레지스터에 저장하여 데이터 처리를 하면
  프로그램 실행 속도가 빨라진다.

- Intel 80386 CPU 범용 레지스터

   8 bit: ah, al, bh, bl, ch, cl, dh, dl
  16 bit: ax, bx, cx, dx, si, di, bp
  32 bit: eax, ebx, ecx, edx, esi, edi, ebp, esp, ...


* General purpose registers

31        16 15   8 7    0   16-bit  32-bit
+-----------+------+------+
|           |  AH  |  AL  |    AX     EAX        
+-----------+------+------+
|           |  BH  |  BL  |    BX     EBX
+-----------+------+------+
|           |  CH  |  CL  |    CX     ECX
+-----------+------+------+
|           |  DH  |  DL  |    DX     EDX
+-----------+------+------+
|           |      SI     |           ESI
+-----------+-------------+
|           |      DI     |           EDI
+-----------+-------------+
|           |      BP     |           EBP
+-----------+-------------+
|           |      SP     |           ESP
+-----------+-------------+

  - 레지스터 조합 관계
    AX = AH + AL
    EAX = EXTENDED 16 BIT + AX


* Control registers

  - EFLAGS: 32비트, 상태 레지스터, 각 종 연산의 결과 상태를 저장한다.
  - EIP: 32비트, Instruction Pointer, 다음 실행할 명령코드의 주소를 기억

* Segment registers

  - CS(Code Seg.), SS(Stack Seg.), DS(Data Seg.), ES, FS, GS
  - 16 비트
  - Virtual Memory addressing, Paged memory addressing, memory protection
  - Linux/i386는 flat memory model을 사용
    CS, DS, ES, SS 모두 서로 겹치는 동일한 주소영역을 사용

            
1.3.3 명령코드 내(instruction operand: immediate operand)

  예) 어셈블리 명령: mov eax, 4
          명령 코드: b8 04 00 00 00
                        ~~~~~~~~~~~  
1.3.4 기타

  IO port
  파일, 하드디스크, CDROM, 비디오 램, 키보드, 스캐너, 마우스, ...


1.4 기본 데이터 처리 명령

1.4.1 복사

- 명령 형식: mov  dest, source

- 예

  assembly Language              C Language

segment .data
hello    db "hello", 0         ; char hello[6] = "hello";

segment .bss
number   resd 10               ; int number[10];

segment .text
  mov eax, ebx                 ; (int) eax = (int) ebx;
  mov ax,  1                   ; (int) ax = 1;
  mov esi, hello               ; (char *) esi = &hello;
  mov al, [hello]              ; (char) al = *hello;
  mov edi, dword [hello]       ; (int) edi = *((int *)hello);
  mov byte [hello + 2], ah     ; hello[2] = (char) ah;
  mov [number + 4 * eax], edx  ; number[eax] = edx;
  mov [esi], eax               ; *(int *)esi = eax;
  mov dword [number], 1        ; *number = 1;

- 옳지 않은 명령

  mov eax, ah                  ; 레지스터 크기가 서로 다르다.
                               ; 1.4.3 형변환 참조
                               ; movsx eax, ah

  mov [number + 4], [number]   ; mov mem, mem 형식의 명령코드는 Intel CPU가
                               ; 지원하지 않는다.
                               ; mov eax, [number]
                               ; mov [number + 4], eax

  mov [number], 1              ; number 주소에 저장되는 값의 크기가 byte인지
                               ; double word인지 구별할 수 없다.
                               ; mov byte [number], 1
                               ; mov dword [number], 1

  * 오류 메시지

    [2 data]# nasm -felf datatype.asm
    datatype.asm:22: error: invalid combination of opcode and operands


- SIB 형식 주소 지정

  [Scale * Index reg. + Base reg. + Displacement] 형식의 주소지정
  여기서 scale은 1, 2, 4, 8 만 허용된다.

  mov dword [ebp + 8], eax             ; ((int *)ebp)[2] = eax;

  mov dh, byte [hello + eax]           ; dh = ((char *)hello)[eax];

  mov ebx, arr                         ; struct st {
  mov eax, i                           ;    char c[6];
  mov dx,  1                           ;    short int w;
  mov word [ebx + 8 * eax + 6], dx     ; } arr[10];
                                       ; // size of struct st == 8
                                       ; // offset of st.w == 6
                                       ;
                                       ; arr[eax].w = 1;


  mov esi, hello + 8                   ; esi = &hello[8];

  lea esi, [ebp + 8]                   ; esi = &((char *)ebp)[8];
                                       ; mov esi, ebp + 8 은 잘못된 표현


1.4.2 산술/논리 연산

- 더하기

  add  dest,  src      ; dest += src

  add  eax,   2        ; eax += 2;
  add  ecx,   eax      ; ecx += eax;
  add  eax,   [number] ; eax += *number;
  
  inc  dest            ; dest++

  inc  eax
  inc  dword [number]  ; inc [number]는 오류를 발생시킨다.
                       ; [number]에 대한 데이터 크기를 지정해야한다.
                       ; 데이터 크기: byte, word, dword, qword

- 빼기

  sub  dest, src       ; dest -= src;
  dec  dest            ; dest--;

- 곱하기

  부호없는 정수에 대한 곱셈: mul
  부호있는 정수에 대한 곱셈: imul

형식)
  imul  dest   source1   source2   action
  ----------------------------------------------
  imul         reg/mem             ax = al * source1 (source1이 8비트)
                                   dx:ax = ax * source1 (source1이 16비트)
                                   edx:eax = eax * source1 (source1이 32비트)
  imul  reg,   reg/mem             dest *= source1
  imul  reg,   reg/mem,  immed     dest = source1 * source2

예)
  imul bl               ; ax = al * bl;
  imul bx               ; dx:ax = ax * bx;
  imul ebx              ; edx:eax = eax * ebx;
  imul edx, eax         ; edx *= eax;
  imul edx, [number]    ; edx *= eax;
  mul  edx, ecx, 8      ; edx = ecx * 8
  mul  edx, [number], 8 ; edx = number * 8

  mul  [number], eax    ; 허용하지 않음, dest는 레지스터만 가능
  
- 나누기

  부호없는 나눗셈: div
  부호있는 나눗셈: idiv

                          source의 크기에 따라           몫  나머지
  div  source           ;      ax div  8bit-source  -->  al  ah
                        ;   dx:ax div 16bit-source  -->  ax  dx
                        ; edx:eax div 32bit-source  -->  ax  dx

예) C와 비슷한 코드
      esi = ebx / ecx;
      edi = ebx % ecx;

  어셈블리 코드
      mov  eax, ebx  
      cdq             ; (long long) edx:eax = (long long) eax; // 형변환
      idiv ecx        ; edx:나머지, eax:몫 <-- edx:eax idiv ecx
      mov  esi, eax
      mov  edi, edx

- 부호 바꾸기(unary -)

  neg ebx             ; ebx = - ebx;
  neg dword [number]  ; number = - number;
  
- 논리 연산

  and eax, 4          ; eax &= 4
  or  ebx, ecx        ; ebx |= ecx
  not eax             ; eax ~= eax;
  xor eax, eax        ; eax ^= eax;  // eax = 0;

  x  y  x xor y
  -------------
  0  0     0
  0  1     1
  1  0     1
  1  1     0
  ------------

- 논리 shift

  mov eax, 0xFFFF1234
  shl eax, 4          ; eax <<= 4;  // eax = 0xFFF12340
  shr eax, 4          ; eax >>= 4;  // eax = 0x0FFFF123

  shl eax, 3          ; eax *= 8;   //  8 = 2 * 2 * 2
  shr eax, 4          ; eax /= 16   // 16 = 2 * 2 * 2 * 2

- 산술 shift: 부호(MSB)가 유지된다.

  mov eax, 0xFFFF1234
  sal eax, 4          ; eax <<= 4;  // eax = 0xFFF12340
  sar eax, 4          ; eax >>= 4;  // eax = 0xFFFFF123

1.4.3 형 변환

- movzx: unsigned 형 변환
  movsx: signed 형 변환

  형식: movzx/movsx  reg, reg/mem

  예:  movzx  ax,   al             ; 16bit <-- 8bit
       movsx  ebx,  ax             ; 32bit <-- 16bit
       movsx  eax, word [number]   ; 32bit <-- 16bit

- cbw  ; convert byte to word,                  ax <-- al,  short <-- char
  cwd  ; convert word to double word,        dx:ax <-- ax,  int   <-- short
  cwde ; convert word to double word,          eax <-- ax,  long  <-- short
  cdq  ; convert double word to quad word, edx:eax <-- eax, long long <-- long


- 큰 크기에서 작은 크기의 형으로 형변환

  * long(32비트) --> short(16비트)
    ax는 eax(32비트)의 하위 16비트이므로 ax의 값은 32비트(long) eax 값에 대한
    16비트(short) 형변환 값이라 할 수 있다.

  * 예:
    mov eax, -10
    mov dh, al       ;  al = (char) eax;

'Asembly programming' 카테고리의 다른 글

어셈 비교 연산(if)  (0) 2009/05/11
5월 8일(금) 어셈블리 곱셈  (0) 2009/05/10
어셈블리 작성 준비 단계  (0) 2009/05/10
어셈블리어 기초코드  (0) 2009/05/10
데이터 처리 기초명령  (1) 2009/05/10
어셈블리 데이터 표현  (0) 2009/05/10
Posted by 쏠쓰

트랙백 주소 :: http://solosols.tistory.com/trackback/11 관련글 쓰기