더하기 빼기 (Addition and Subtraction)
1. INC and DEC Instructions
- INC (increment) instruction adds 1 to operand
- DEC (decrement) instruction subtracts 1 from operand
operand로 memory 또는 register사용 가능
.data
myWord WORD 1000h
.code
inc myWord ;myWord = 1001h (메모리 값 감소)
mov bx,myWord
dec bx ;BX = 1000h (bx레지스터 감소)
- 연산을 통해서 flag가 세팅이 된다.
- Overflow, Zero, Sign, Auxiliary Carry, and Parity flags 들은 피연산자의 값에 따라 변화된다.
- 다만, INC와 DEC 연산은 Carry flag에 영향을 주지 않는다. ( 예외적인 케이스..! 기억하기! ,역사)
2. ADD Instruction
- 소스에 있는 operand를 dest에 있는 operand에 더해주는 역활
ADD dest, source
- source값은 변경 x dest 값만 변경
- dest+=source 라고 생각해도 됨
- 가능한 피연산자 집합은 MOV 명령어와 동일
.data
var1 DWORD 10000h
var2 DWORD 20000h
.code
mov eax, var1. ;EAX = 10000h
add eax, var2. ;EAX = 30000h
- 예제코드 var1 리틀앤디안으로 저장됨. → 다만 레지스터까지 리틀앤디안으로 저장되는 건 아닙니다.
- flag :The Carry, Zero, Sign, Overflow, Auxiliary Carry, and Parity flags 가 세팅된다.
3. SUB Instruction
- 소스에 있는 operand를 dest에 있는 operand에 빼주는 역활
- SUB dest, source
- dest -= source와 동일
- 가능한 피연산자 집합은 mov와 ADD와 동일
.data
var1 DWORD 30000h
var2 DWORD 10000h
.code
mov eax, var1. ;EAX = 30000h
SUB eax, var2. ;EAX = 20000h
- flag : The Carry, Zero, Sign, Overflow, Auxiliary Carry, and Parity flags 가 세팅
4. NEG Instruction (negate)
- 주어진 수를 signed라고 가정하고 부호를 바꿔주는 역활 (2의 보수를 활용해서 부호반전)
- NEG reg
- NEG mem
- 대상 피연산자의 모든 비트를 반전하고 1을 더하면 2의 보수를 찾을 수 있습니다.
- flag : The Carry, Zero, Sign, Overflow, Auxiliary Carry, and Parity flag 세팅
Implementing Arithmetic Expressions
C++에서 사용되는 연산을 어셈블리어로 바꿔보기!
Rval = -Xval + (Yval - Zval);
- 다음과 같은 부호화된 32비트 변수가 사용된다고 가정한다.
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40
- 먼저 Xval의 복사본을 Neg연산을 사용해서 레지스터에 저장한다.
- 그 후 Yval을 레지스터에 복사하고 Zval을 뺀다.
- 마지막으로 2개는 더해진다. (EAX와 EBX)
;first term: -Xval
mov eax, Xval
neg eax
;EAX = -26
;second term : Yval - Zval
mov ebx, Yval
sub ebx, Zva ;EBX = -10
; add the terms and store :
add eax, ebx
mov Rval, eax ;-36
덧셈과 뺄셈에 의해 영향을 받는 flag들
- 산술명령을 실행할 때 결과에 대해 알고싶은 경우가 많다.
- 음수인지 양수인지 0인지
- 대상 피연산자가 너무 크거가 작지는 않은지
- 이런 것을 보면 계산오류를 감지하는데 더 도움이 될 수 있다.
- 그것들을 알기 위해서 Cpu status flag를 사용한다.
- 산술 연산 결과를 체크하는데 사용할 수 있다.
- 프로그램 로직의 기본 도구인 conditional branching (분기 명령 -if 문 예시)을 활성화 할 수 있다.
status flag 종류
- The Carry flag : indicates unsigned integer overflow
- The Overflow flag : indicates signed integer overflow
- The Zero flag : indicates that an operation produced zero
- The Sign flag : indicates that an operation produced a negative result (MSB가 설정되있으면 설정)
- The Parity flag : indicates whether or not an even number of 1 bits occurs in the least significant byte of the destination operand, immediately after an arithmetic or boolean instruction has executed
- 해석 : 산술 또는 부울 명령잉 실행된 이후에 대상 피연산자의 최하위 바이트에 짝수 1비트가 있는지 확인한다.
- 연산의 결과로써 최하위 바이트를 본다. 그 안에 1이 몇개 있는지를 보는 것이다. (거의 사용이 잘 안되지만 conditional branch에서 사용이 되곤 한다.)
- The Auxiliary Carry flag : is set when a 1 bit carries out of position 3 in the least significant byte of the destination operand
- 해석 : 보조캐리플래그는 대상 피연산자의 최하위 바이트에서 1비트가 위치 3에서 캐리될 때 설정된다?
- 연산의 결과로써 최하위 바이트를 보는데 그곳의 3번 위치에 캐리가 발생했는지를 확인한다.
1. Unsigned Operations: Zero, Carry, and Auxiliary Carry
- Zero flag : 산술 연산의 결과가 전부 다 0으로 세팅이 되면 1로 세팅됨 (이건 unsigned 연산 flag라고 보기엔 조금 곤란하다.)
- Addition(덧셈) and the Carry Flag :
- 두개의 부호없는 정수를 더할 때 carry flag 는 대상 피연산자의 MSB에서 캐리된 복사본이다.
- 합이 대상 피연산자의 저장소 크기를 초과하는 경우 CF = 1이다.
- Subtraction(뺄셈) and the Carry Flag
- 특징 : NEG 명령을 적용하면 Carry flag는 1로 설정이 된다.
- INC 명령과 DEC 명령은 carray flag에 영향을 미치지 않는다.
- Auxiliary Carry Flag (AC) (보조 캐리플래그)
- 3번비트에서 캐리가 발생했는지 확인한다.(마지막 바이트에서)
- 왜 있냐면 ..! (BCD방식이라는게 있었는데, 10진수를 4비트를 이용해서 표현하는 방식에 영향 - 사람이 보기 편함)
- Parity Flag (PF)
- 가장 하위 바이트만 본다.
- 하위 1바이트안에 1비트가 짝수면 1 홀수면 0일때 사용한다.
- JUMP를 할 때 사용 (분기문에서)
2. Signed Operations: Sign and Overflow Flags
- Sign Flag
- 이 플래그는 산술연산 결과가 음수일 때 설정된다.
- MSB를 보고 결정!!
- Overflow Flag
- 이 플래그는 부호있는 연산결과가 + 끼리 연산했더니 - - 끼리 더했더니 + 가 되는경우 overflow라고 한다.
- CPU가 Overflow를 감지하는 방법
- 최상위 비트에서 carry_out과 carry_in 을 XOR연산을 함으로써 설정이 된다.
- 즉 올라오는 비트와 나가는 비트가 동시에 있는 경우나 올라오는 비트도 없고 나가는 비트도 없는 경우 overflow로 세팅되지 않는다.
- 그 외의 하나만 세팅이 되는 경우에 1로 세팅이 된다.
- 결과 값은 Overflow flag에 배치된다.
- 최상위 비트에서 carry_out과 carry_in 을 XOR연산을 함으로써 설정이 된다.
- NEG 명령
- -128에 NEG 명령을 하면 overflow가 발생하는 경우가 존재한다.
- 교수님께서 자꾸 강조!! : sign과 unsigned는 기계적인 입장에서는 아무런 상관이 없고 사람이 해석하기에 따른 것이다. - 따라서 프로그래머가 어떤 플래그를 보고 어떤 플래그를 무시할지를 결정해야만 한다.
Uploaded by N2T
728x90
'CSE > system programing' 카테고리의 다른 글
[시스템 프로그래밍 6-3] 어셈블리어 JMP와 LOOP명령어 (0) | 2023.04.06 |
---|---|
[시스템 프로그래밍 6-2] 어셈블리어 데이터 관련 연산자와 간접 주소방식 (0) | 2023.04.06 |
[시스템 프로그래밍 5-3] 데이터 전송지침 , 피연산자 유형(Operand Types) (0) | 2023.03.30 |
[시스템 프로그래밍 5-2] 어셈블리어 기호상수 Symbolic Constants (0) | 2023.03.30 |
[시스템 프로그래밍 5-1] 어셈블리 기본 데이터 타입 (0) | 2023.03.30 |