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 |


