외로운 Nova의 작업실

Assembly 언어 공부 - 15(산술 이론 및 실습) 본문

Programming/Assembly

Assembly 언어 공부 - 15(산술 이론 및 실습)

Nova_ 2022. 7. 30. 22:41

안녕하세요, 오늘은 덧셈과 뺄셈 관련하여 어셈블리어를 배워볼까합니다.

 

INC, DEC

형식 : INC reg/mem, DEC reg/mem

INC는 피연산자의 값을 1증가시키는 명령어 입니다. 이에 반해, DEC는 피연산자의 값을 1 감소시키는 명령어 입니다.

 

ADD

형식 : ADD dest, source

ADD는 source의 값을 dest의 값에 더하여 dest에 저장합니다.

 

SUB

형식 : SUB dest, source

SUB은 source의 값을 dest의 값에서 뺀다음 dest에 저장합니다.

 

NEG

형식 : NEG reg/mem

NEG는 피연산자를 2의 보수로 계산하여 부호를 바꿉니다.

 

산술 연산의 결과는 상태 플래그를 변화시킵니다. 이제 산술연산의 결과로 어떻게 상태 플래그가 변하는지 알아봅시다.

 

Carry플래그

부호가 없는 정수들끼리 계산일때, 연산의 결과가 오버플로가 난다면 1로 설정됩니다.

Byte는 8비트로  0~255 까지 표현이 가능합니다. 그렇다면 Byte 계산에서 255 + 1을하면 256 이기 때문에 오버플로가 발생하여 Carry 플래그가 1로 설정됩니다. 반대로, 1-3을 하게되면 결과는 -2로 부호가 없는 정수가 아닌 값이 나오기때문에 Carry 플래그는 1로 설정됩니다.

 

Overflow 플래그 : 부호가 있는 정수끼리 계산할때, 연산의 결과가 오버플로가 난다면 1로 설정됩니다.

Byte는 8비트로 -128~+127 까지 표현이 가능합니다. 그렇다면 Byte 계산에서 126 + 5 를 하게되면 131이기때문에 오버플로가 발생하여 Overflow 플래그가 1로 설정됩니다. 반대로 -127 + (-100)을 하게되면 -227이므로 Overflow 플래그가 1로 설정됩니다.

또한 Overflow 플래그는 Carry 플래그와 MSB(최상위 비트)를 XOR 시켜서 구하게됩니다.

 

Zero 플래그 : 연산의 결과가 0이라면 1로 설정됩니다.

1-1을 하면 0이기때문에 Zero 플래그가 1로 설정됩니다.

 

Sign 플래그 : 연산의 결과가 음수라면 1로 설정됩니다.

(-1) - 3은 -4이기때문에 Sign 플래그는 1로 설정됩니다.

 

Parity 플래그 : 연산의 결과에서 최하위 바이트에 1의 비트의 개수가 짝수개라면 1로 설정됩니다.

연산의 결과로 AL의 값이 10001101 이라면 1이 4개이므로 Parity 플래그는 1로 설정됩니다.

 

보조 Carry 플래그 : 연산의 결과에서 최하위 바이트 비트 3에서 1이 캐리로 발생하면 1로 설정됩니다.

00001000 + 00001000 을 할때 3 비트에게 캐리 1이 발생하므로 이때 보조 Carry가 1로 설정됩니다.

 

이제 실제로 실습을 해봅시다.

include 	c:\assembly\irvine32.inc
includelib  c:\assembly\irvine32.lib
includelib  c:\assembly\kernel32.lib
includelib  c:\assembly\user32.lib

.data
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40

.code
main PROC

    ;INC, DEC
    mov ax, 1000h
    inc ax              ;ax = 1001h
    call DumpRegs
    dec ax              ;ax = 1000h
    call DumpRegs
    
    ;Expression : Rval = -Xval + (Yval - Zval)
    mov eax, Xval
    neg eax             ;eax = - 26
    mov ebx, Yval       ;ebx = 30
    sub ebx, Zval       ;ebx = -10
    add eax, ebx        ;eax = -36
    mov Rval, eax       ;Rval = -36
    call DumpRegs

    ;Zero flag example : 
    mov cx, 1
    sub cx, 1           ;ZF = 1
    call DumpRegs
    mov ax, 0FFFFh
    inc ax              ;ZF = 1
    call DumpRegs
    
    ;Sign flag example :
    mov cx, 0
    sub cx, 1           ;SF = 1
    call DumpRegs
    mov ax, 7FFFh
    add ax, 2           ;SF = 1
    call DumpRegs

    ;Carry flag example : 
    mov al, 0FFh
    add al, 1           ;CF = 1, AL = 00
    call DumpRegs

    ;Overflow flag example : 
    mov al, +127
    add al, 1           ;OF = 1
    call DumpRegs
    mov al, -128
    sub al, 1           ;OF = 1
    call DumpRegs

    exit

main ENDP
END main

위 코드를 실행 하게되면 아래와 같이 나옵니다.

빨간색 밑줄 친 부분을 따라가보면 쉽게 잘 된것을 확인 할 수 있습니다.

Comments