산술연산과 논리연산의 차이점
산술연산은 연산대상이 수
논리연산은 연산대상이 단순한 비트 단위로 봄 (비트 단위의 연산)
EFLAGS – 현재 CPU의 상태 32bit register
32비트 중에서 6개의 비트에 관심있음
산술 연산과 논리 연산의 명령실행의 결과에 대한 부가적인 정보가 flag값에 반영 – 값이 변할 수 있음
EFLAG - status flag
Some bits of EFLAGS can change for arithmetic and logic instructions
ex. add eax, ebx
eax - destination operand,
ebx - source operand
? 부호있는 정수, 부호없는 정수, BCD인지 누가 정함?
-프로그래머가 정함
변수선언 int x; signed integer라 선언 – x는 무조건 부호있는 정수
Unsigned y – y는 무조건 부호없는,,
CPU는 부호있는 정수인지 없는 정수인지 상관 안씀
Addition(단순 덧셈), Increment(증가), Add-with-carry(carry를 포함하는 덧셈) and Exchange-and-add
[ ] – 메모리 피연산자 (operand)
Subtraction, Decrement and Subtract-with-borrow
표현은 비교연산이지만 실제로 일어나는 동작은 뺄셈과 동일한 동작임.
CMP EBX, EAX
이때 뺄셈 연산이 이루어지지만 연산의 결과값이 EBX에 저장되지는 않음.
그러나 status flag 값들이 변해서 cmp 다음에 오는 조건부 분기 명령이 영향을 받음(분기를 하거나 안하거나..)
JL : EBX가 EAX 보다 작으면 SIB로 분기해라
덧셈과 뺄셈 연산에서는 대상 operand가 signed인지, unsigned인지 구분하지 않음.
mul bl
곱하는 수가 8비트 bl 이고 곱해지는 수는 al 레지스터에 있음.
8비트 두수를 곱해서 생긴 16비트 수는 ax에 저장됨.
imul cx, dx, 12H
cx = dx * 12H
mul ecx
곱하는 수가 ecx에 들어가있고 곱해지는 수는 eax에 있음.
32비트 두수를 곱해서 생긴 64비트 수는 edx와 eax에 저장이 됨.
C and O bits are cleared if most significant 8 bits of the 16-bit product are zero
(result of an 8-bit multiplication is an 8-bit result).
8비트 두수 곱셈을 했는데 결과적으로 16비트 수가 나올텐데 16비트 수의 상위 8비트가 0라면 CF, OF 가 clear됨.
즉 8비트 두수 곱셈을 했는데 여전히 8비트 수라면 CF, OF가 clear 됨.
Division by zero and overflow generate errors.
0으로 나눌수 없으니까 operand가 0이면 에러 발생
dibision by zero = exception.
exception: cpu가 명령을 실행하는 도중에 치명적인 오류를 발생한 것.
exception 발생하면 프로그램이 강제 종류됨(프로그램이 죽음).
Overflow occurs when a small number divides a large dividend.
매우 큰수를 매우 작으로 나뉘게 됐을 때 오버플로우 발생.
몫이든 나머지든 정해진 비트수(자릿수)로 수용이 안될 경우.
Allow bits to be set, cleared and complemented
operand의 일부 비트 값을 조작(set, clear, complement)하는데 사용이 됨.
set: 비트를 1로 만듬
clear: 비트를 0으로 만듬
complement: 비트의 값을 0을 1로, 1을 0으로 바꿈
Commonly used to control I/O devices.
Logic operations always clear the carry and overflow flags.
논리 연산 실행 후 CF, OF는 clear 됨.
1 and 1 일때만 1
Commonly used with a MASK to clear bits
clear하고 싶은 부분은 0으로, 값을 그대로 유지하고 싶은 부분은 1로 해서 and 연산함
주어진 값은 al, 내가 설정한 값(mask)은 bl
and 연산 후 결과값은 al에 저장
이때 mask는 8비트 크기의 위쪽 4비트를 clear시키는 and mask
0 or 0 일떄만 0
Commonly used with a MASK to set bits
8비트 값이 있을 때 아랫쪽 4비트를 set하고 싶을 때
나머지 위쪽 4비트는 값이 그대로 나옴
이 mask는 8비트 크기의 하위 4비트를 set시키는 or mask
두비트 값이 같으면 0, 다르면 1나옴
Commonly used with a MASK to complement bits
바x 원래의 비트들의 반대
이 mask는 complement하고 싶은 비트들은 1을 대응시키고 그대로 유지하고 싶은 비트들은 0을 대응
8비트 중에서 아랫쪽 4비트를 complement 시키는 xor mask
TEST: Operates like the AND but doesn't effect the destination.
Test는 결과값이 저장되지는 않지만 결과에 따른 flag register 값만 변함
Sets the Z flag to the complement of the bit being tested:
Al(8비트)와 4(0000 0100)을 and 시킴 – 0에 해당하는 값은 0이 나오고, 나머지 한비트는 al의 값에 따라 달리짐.
al register의 비트위치 2번에 해당하는 값이 0인지 1인지 test하는 명령
jz – 분기해라 조건 분기 명령 (ZF=1이면 LABEL로 분기해라)
일정한 비트 수만큼 왼쪽 또는 오른쪽으로 값들을 이동을 시킴
종류는 4가지.
Shift: Logical shifts insert 0, arithmetic right shifts insert sign bit.
Shift 대상 오퍼랜드와 shift count 오퍼랜드로 구성; count 오퍼랜드는 최대 5bit만 유의미함 (32자리 이상 shift 하는 것은 의미 없음)
shift 된 비트(사라지는 비트)는 CF로 들어감
SHL과 SAL은 기본적으로 동작이 동일
SHR
SAR
원래 operand의 최상위 비트 값으로 새로 채워짐.
shld(left) / shrd(right)
Rotate: Rotates bits from one end to the other or through the carry flag.
한쪽으로 빠져나간 비트들이 반대편 방향의 빈곳으로 채워지는 동작이 이루어짐.
rotate의 종류 4가지.
Commonly used to operate on numbers wider than 32-bits:
32비트보다 더 큰 수에 사용되기도 함.
46비트경우, 16비트 레지스터 세개 dx, bx, ax 에 넣음.
<논리연산의 경우>
왼쪽으로 나간 값이 오른쪽으로 들어오기도 하지만,
왼쪽으로 나간 값이 CF로 들어가기도 함.
5비트 rotate 했을 때 마지막 비트가 CF에 들어감.
<산술연산의 경우>
CF 한비트까지 포함해서 총 33 비트값을 rotate 한다고 생각하면 됨.
Bit Scan Instruction (80386 and up):
String Scan Instructions:
스트링 연산과 관련된 명령