본문 바로가기

교육/ASSEM

[어셈블리어] adc와 Jump

4.5 Addition and Subtraction of Larger Numbers

adc 
  • add 와 기능은 같지만, carry(자리올림수)를 포함해서 덧셈을 하기 때문에 64bit의 연산이 가능하다.
.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

.STACK  4096           

.DATA
Ndr1Hi     DWORD     ?
Ndr1Lo     DWORD     ?
Ndr2Hi     DWORD     ?
Ndr2Lo     DWORD     ?


.CODE                          
_start:
     mov Ndr1Lo, 0FFFFFFFFh
     mov Ndr2Lo, 0FFFFFFFFh
     mov Ndr1Hi, 0
     mov Ndr2Hi, 0

     mov eax, Ndr1Lo
     add  eax, Ndr2Lo
     mov Ndr1Lo, eax
     mov eax, Ndr1Hi
     adc  eax, Ndr2Hi
     mov Ndr1Hi, eax
    
        INVOKE  ExitProcess, 0 
PUBLIC _start                  

END




Ndr1Lo(ffff ffff)와 Ndr2Lo(ffff ffff)를 add하면 carry(자리올림수)가 발생하여
1 ffff fffe의 값이 나온다.
이때 자리올림 수 carry의 값(여기서는 1)을 보존하기 위해 adc를 호출하게 되는 것


adc eax, Ndr2Hi하여 carry발생한 값을 eax에서 확인하면 아까 발생한 1이 보존되어 있음.
그리고 Memory를 확인하면 리틀엔디안 방식으로 
01 00 00 00 fe ff ff ff로 저장되어있음.

빅엔디안 방식으로 확인하면 ff ff ff fe 01 00 00 00으로 정상적으로 carry를 포함한 64bit연산값을 확인 할 수 있다.





5.1 Unconditional Jumps
Jump문 - C로치면 goto문으로 생각하면 된다.

jmp = 해당하는 주소로 점프하고 싶을 때 사용하는 명령어

.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h           
cr      EQU     0dh 
Lf      EQU     0ah   

.STACK  4096      

.DATA              
sum              DWORD     ?
explain          BYTE     cr, Lf, "As you input numbers one at a time, this", cr, Lf
                    BYTE     "program will report the count of numbers so far, ", cr, Lf
                    BYTE     "the sum so far, and the average.", cr, Lf, Lf, 0
prompt          BYTE     "number? ", 0
number          BYTE     16     DUP     (?)
countLabel     BYTE     "count", 0
sumLabel       BYTE     "     sum", 0
avgLabel        BYTE     "     average", 0
value             BYTE     11     DUP     (?), 0
nextPrompt     BYTE     cr, Lf, Lf, "next ", 0

.CODE                          
_start:
          output     explain
          mov          sum, 0
          mov          ebx, 0

forever:
          output     prompt
          input       number, 16
          atod        number

          add          sum, eax
          inc          ebx

          dtoa        value, ebx
          output     countLabel
          output     value

          dtoa        value, sum
          output     sumLabel
          output     value

          mov          eax,sum
          cdq          ;확장
          idiv          ebx
          dtoa        value, eax
          output     avgLabel
          output     value

          output     nextPrompt
          jmp          forever

PUBLIC _start                  

END                        






jmp          forever
를 주었기 때문에 해당하는 주소인 forever라벨로 점프하여 무한 반복하고있는 모습
-강제적으로 종료하지 않는 한 무한 루프를 돌게됨

count변수는 몇번째의 실행인지를 세고있고 sum은 지금까지의 number입력값을 더하고 있다.
(average는 평균값)




5.2 Conditional Jumps, Compare Instructions, and if Structures
비교명령

jz   = 제로플래그가 발생할 경우 (ZF = 1)
jnz = 제로플래그가 발생하지 않았을 경우 (ZF = 0)
jns = not sigend 부호가 없을 시 (양수일 때)
cmp = operand1, operand2 를 비교하는 비교연산자 

.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

include io.h

cr     equ     0dh
Lf     equ     0ah

.STACK  4096           

.DATA
prompt1     BYTE     "Input Number ", cr, Lf, 0
prompt2     BYTE     "Small ", cr, Lf, 0
prompt3     BYTE     "Big ", cr, Lf, 0
prompt4     BYTE     "Equal ", cr, Lf, 0
prompt5     BYTE     "End Program ", cr, Lf, 0
number1     BYTE     16     DUP     (?)

.CODE                          
_start:
          output      Prompt1
          input        number1, 16
          atoi          number1
          mov         edx, 10
          sub          edx, eax

          jz     EQUAL       ; 제로플래그가 발생할 시 EQUAL로 점프
          jns     SMALL      ; jns = 음수가 아닐때 not sigend
          jmp     BIG          ; 그냥 BIG으로 점프

     EQUAL :
               output prompt4
               jmp ENDPRG     ; 프로그램을 종료시키는 라벨로 점프

     SMALL :
               output prompt2
               jmp ENDPRG     ; 프로그램을 종료시키는 라벨로 점프

     BIG     :
               output prompt3
               jmp ENDPRG     ; 프로그램을 종료시키는 라벨로 점프
              
     ENDPRG :
               output prompt5


        INVOKE  ExitProcess, 0 
PUBLIC _start                  

END                    



        



cmp 비교연산

operand1에서 operand2의 값을 빼서 플래그를 확인하여 비교한다.

4번의 경우는
 F9 - F6 = -7 - (-10) 이기 때문에 03의 값이 나옴

8, 9번의 경우는 각각 양수와 음수의 영역의 대역을 넘어서 OF가 발생
8 -> 양수의 대역을 넘어 음수가 됨
9 -> 음수의 대역을 넘어 양수가 됨


cmp 연산가능한 오퍼랜드





잘못된 cmp비교연산
  • cmd에서 연산가능한 operand를 확인하면 immediate(상수)는 항상 두번째 operand에 와야한다.




Figure 5.5 Conditional jump instructions
-두 명령어씩 한 쌍-

ja는 CF와 ZF플래그가 항상 0일 때, 즉 operand1 > operand2를 만족할 때
jnbe는 같지않고, 미만이 아닐 때 (ja와 동급인데 ja가 쓰기 편함)
1byte일 때는 short 77 1byte이상일 때는 near OF87으로

jae는 이상일 때 같거나 이상일 때
jnd는 이상일 때