1.
산술 연산
산술 연산자를
위해 레지스터를 사용 하면,
산술 연산을 할 수 있다.
산술 연산의 형태는
일반적으로 다음과 같다.
operation
register, value/register
첫 번째 레지스터가
연산의 대상입니다.
예를 들어:
add
rax, 5
sub
rbx, rax
수학 연산 리스트
동작 이름
|
동작 이름(서명)
|
설명
|
add
a, b
|
-
|
a
= a+b
|
sub
a, b
|
-
|
a
= a-b
|
mul
reg
|
imul
reg
|
rax
= rax*reg
|
div
reg
|
idiv
reg
|
rax
= rax/reg
|
neg
reg
|
-
|
reg
= -reg
|
inc
reg
|
-
|
reg
= reg +1
|
dec
reg
|
-
|
reg
= reg – 1
|
adc
a, b
|
-
|
a
= a+b+CF
|
add
a, b
|
-
|
a
= a-b-CF
|
2.
ASCII
ASCII는
컴퓨터가 텍스트 문자열을 나타내는 방법.
컴퓨터는 숫자를
저장할 수 있으므로 ASCII는
숫자를 특정 문자 (문자,
숫자,
기호 등)에
매핑하는 방식으로 작동 한다.
ASCII는
7
비트 이진 코드를 사용 하여 문자를
나타낸다.
그러나 8
비트 1바이트
정보의 기본 단위 이기 때문에 현 컴퓨터는 일반적으로
8비트
코드인 확장 ASCII을
지원한다.
ASCII
표.
3.
숫자 화면 출력
다음은 0과
9사이의
단일 숫자를 표시하기 위한 매우 간단한 서브루틴이다.
표시되는 숫자는
rax
레지스터에서 가져온다.
section
.data
digit
db 0,10
...
_printRAXDigit:
add
rax, 48
mov
[digit], al
mov
rax, 1
mov
rdi, 1
mov
rsi, digit
mov
rdx, 2
syscall
ret
rax
레지스터의 값은 48
씩 증가한다.
ASCII
표를 확인하면 48은
"0"문자
값과 매칭 되며,
char형이므로 "1"문자를
표현 할 수 있다.
ASCII
코드 테이블 추가 필요
section
.data
digit
db 0,10
...
...
_printRAXDig:
add
rax, 48 " 0을 의미 함.
mov
[digit], al
mov
rax, 1
mov
rdi, 1
mov
rsi, digit
mov
rdx, 2
syscall
ret
rax
레지스터의 하위 바이트는 메모리 주소
"digit"로
이동
_printRAXDig:
add
rax, 48 " 0을 의미 함.
mov
[digit], al " 메모리 주소 이동
mov
rax, 1
mov
rdi, 1
mov
rsi, digit
mov
rdx, 2
syscall
ret
"digit"는
실제로 2
바이트로 정의되며,
0과 10,
줄 바꿈 문자,
개형 문자를 의미한다.
rax 레지스터의 하위 바이트를 "digit"에
로드하기 때문에 첫 번째 바이트 만 덮어 쓰며 개행
문자에는 영향을 미치지 않는다.
그런 다음 2
바이트를 화면에 출력 한다.
길이가 2로
설정되어 있기 때문에 숫자와 개행 문자가 함께 표시됨.
section
.data
digit
db 0, 10
...
...
...
_printRAXDigit:
add
rax, 48
mov
[digit], al
mov
rax, 1
mov
rdi, 1
mov
rsi, digit
mov
rdx, 2
syscall
ret
아래 서브 루틴을
사용하여 해당 숫자를 rax
레지스터에 로드 한 다음 서브 루틴을
호출하여 0-9
사이의 숫자를 표시 할 수 있다.
mov
rax, 7
call
_printRAXDigit
숫자 7을
화면에 출력 한다.
이러한 방법을
통해 산술 연산자를 빠르게 테스트 할 수 있다.
코드
|
출력
|
추론
|
mov
rax, 6 mov rbx, 2 div rbx call _printRAXDigit |
3
|
rax
= 6/2
|
mov
rax, 1 add rax, 4 call _printRAXDigit |
5
|
rax
= 1+4
|
4.
Stack
레지스터와
마찬가지로 스택은 데이터를 임시로 저장하는 또 다른
방법이다.
데이터를 스택(쌓기)에
저장하기 때문에 "스택"이라고
한다.
서류 더미를
상상해보자.
한 장의 용지를 다른 용지 위에 겹쳐
놓으면 지정된 시간에만 스택의 맨 위에 있는 용지의
내용을 볼 수 있다.
스택 중간에 있는
페이지는 위에 있는 페이지 전부를 제거하지 않고는
중간의 스택을 제거 할 수 없다.
push:
스택의 맨 위에 데이터를 추가.
pop
:스택의 맨 위에서 데이터를 제거.
peek:
추가,
제거 없으며 스택을 볼때.
4.1
스택 동작
동작
|
효과
|
push
reg/value
|
값을 스택에 밀어 넣는다. |
pop
reg
|
스택에서 값을 꺼내서 reg에 저장한다. |
mov
reg, [rsp]
|
reg에 peek(보기) 값을 저장한다. |
참고:
일반적으로 레지스터를 사용할 수 있는
위치에서 포인터를 사용할 수도 있다.
"pop
reg"대신 "pop
[label]"을 사용하여 스택의 값을
메모리의 특정 위치로 직접 pop
할 수 있다.
4.2
push
Peek:NULL
|
Peek:4
|
Peek:8
|
Peek:3
|
|||
3
|
||||||
8
|
3
|
|||||
4
|
4
|
4
|
||||
Stack
|
Stack
|
Stack
|
Stack
|
4.3
pop
Peek:3
|
Peek:8
|
Peek:4
|
Peek:NULL
|
|||
3
|
||||||
8
|
8
|
|||||
4
|
4
|
4
|
||||
stack
|
Stack
|
Stack
|
Stack
|
|||
rax:NULL
|
rax:
3
|
rax:
8
|
rax:
4
|
예제 코드
push
4
push
8
push
3
pop
rax
call
_printRAXDigit
pop
rax
call
_printRAXDigit
pop
rax
call
_printRAXDigit
출력 예상
3
8
4