본문 바로가기
전공/시스템 프로그래밍

[시스템 프로그래밍 6 -1] 어셈블리어 더하기 빼기 연산과 그에 따른 flag 세팅

by 뜨거운 개발자 2023. 4. 6.

더하기 빼기 (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에 배치된다.
  • NEG 명령
    • -128에 NEG 명령을 하면 overflow가 발생하는 경우가 존재한다.
  • 교수님께서 자꾸 강조!! : sign과 unsigned는 기계적인 입장에서는 아무런 상관이 없고 사람이 해석하기에 따른 것이다. - 따라서 프로그래머가 어떤 플래그를 보고 어떤 플래그를 무시할지를 결정해야만 한다.


Uploaded by N2T

728x90