분기문 하기에 앞서 사칙연산을 정리해보겠다.

사칙연산하는 C코드의 어셈블리어는 어떻게 구성될까?



(C코드)




컴파일 후 확인해본다!




(어셈블 코드)



저번 글에서 만들었던 형태가 비슷하게 나오는 것을 확인 할 수 있다.

오늘은 분기문을 공부 할 것이다.
jmp는 해당 주소로 이동하는 것이다.

이것을 이용하면 조건문도 만들 수 있고 반복문도 만들 수 있다.
실제로 C코드에서 if와 switch는 jmp 명령어로 이루어져있고
어셈블 차원에서 보면 똑같다.

사용 형식은
jmp addr
이런식으로 써준다.

그렇다면 jmp로 무한루프를 만들어보겠다.




(무한루프 코드)



jmp 명령에 의해 _start로 돌아간다.
_start는 레이블 이름으로 주소값이다. 컴파일 전에 주소값을 우리는 모르니 레이블 이름을 달아주어 사용한다.
컴파일한다.



(컴파일)



컴파일 후 실행해보면



(실행 모습)



실행되는 모습이다.

그렇다면 C코드의 기본적인 if문을 어셈블러로 구현해보자!
먼저 C코드의 기본적인 if문 코드이다.



(if문 코드)




(실행모습)



여기서는 조건 분기를 사용한다. 위의 jmp는 무조건 분기로 다른 조건없이 바로 해당 주소로 넘어가지만 조건분기는 조금 다르다.

조건 분기
 - EFLAGS 레지스터를 참조해서 분기할지 말지를 결정한다.
조건 분기문을 쓰기전에 cmp를 해줘야 EFLAGS에 기록하고 이걸 보고 조건문기문이
동작한다.

 - cmp

조건분기 종류를 살펴보면
 - je (jmp equal) = jz
 - jne (jmp not equal) = jnz
 - jl (jmp less)
 - jg (jmp greater)
 - jnl
 - jng
 - jle
 - jge
 - ja (jmp above) 초과
 - jb (jmp below) 미만
 - jna
 - jnb
 ...

3. cmp : 비교명령어
 cmp vleft vright
 -> 두개의 값이 같은지 비교
- vleft 값과 vright 값의 차를 구한다.
- 그 결과에 따라서 EFLAGS 레지스터의 플래그를 조절한다.
cmp에서 사용하는 flg
- ZF, SF
1) vleft - vright의 결과가 0인 경우
 : ZF = 1, SF=0 -> 두 값이 같다고 판단
2) vleft - vright의 결과가 음수인 경우
 : ZF=0, SF=1 -> 오른쪽이 더 크다.
3) vleft - vright의 결과가 양수인 경우
 : ZF=0,SF=0
조건분기문 사용 직전에 cmp를 해줘야한다.

이를 이용해 기본적인 if C코드를 어셈블러 코드로 구현하면 아래와 같다.



(조건분기문 사용)




(실행결과)



실행 결과 잘 나오는 듯하다.
(하지면 이 코드에는 문제점이 있다.)

값을 5보다 작게 2로 설정하여 확인해보겠다.



(작은 값 입력)




(실행결과)



실행결과를 보니 2가 작음에도 크다고 출력되었다.

왜 이럴까??
원인은 바로 점프하지 않고도 그 아래에 출력해주는 명령문이 있기 때문에 아래 코드가 순차적으로 실행 되었던 것이다. 이것을 막아주기 위해서는 아래 처럼 추가해주면된다.



(추가 코드)




(실행결과)



실행한 결과 작을 때는 이제 출력되지 않는 우리가 원하던 C코드의 동작을 하게 되었다.

다르게 표현을 하자면 jmp문 하나로도 완성 가능하다.



(다른 표현)



C코드를 컴파일 한 내용과 비교해보겠다.
상수끼리 비교하면 컴파일러가 알아서 계산을 해놓아서...
변수를 따로 선언을 해주었다.



(C코드 수정)



컴파일 후 어셈블러를 확인해보면



(어셈블 코드)



우리가 만든 코드와 비슷하게 나온 것을 확인 할 수 있다.

그렇다면 실습으로 아래와 같은 코드를 어셈블 코드로 만들어보자!



(실습 코드)



실습 결과는 아래와 같이 만들 수 있다.



(실습 결과)



jmp 문에 대한 내용이었다.



* 비교연산자
-> 비교를 하는 연산자이다. 종류로는
==       :  같다
!=        : 같지 않다.
왼쪽이 크다는 기준으로
>        : 크다.
<        : 작다
>=      : 크거나같다.
<=      : 작거나 같다

- 문자열도 비교연산자를 쓸 수 있다.  크기 비교도 한다 
: 크기 비교할 때 의미는 크지 않는데 문자마다 숫자값을 가지고 있어서 크기비교연산이 되기는한다.
   하지만 이걸 사용해서 문자 정렬을 하기도 한다.

* 수학식에서는 =  기호가 같다라는 뜻이다.
하지만 프로그래밍 언어에서 = 기호는 assignment 의미로 사용된다.

ex)
10 == 10
결과 -> True 
여기서 True는  문자열이 아니다. , 숫자 1과 같은 의미를 가지고있다. (반대로 False는 0을 의미한다.)
문자열에서는 '', "" 로 표현된다.

* bool's 논리식
 - AND(그리고) , OR(또는), NOT(아닌)

NOT 은 피연산자 하나만 온다.  (AND, OR 는 피연산자가 두개 와야한다.)

ex)
 A가 참이고 B가 참이면 결과는 참이다.
 A and B -> True   (A,B 에 보통 비교 연산자가 온다.) 

 A가 참이거나 B가 참이면 결과도 참이다. 
A or B  -> True   (A,B 둘 중 하나만 참이여도 결과는 참이다.)
 
A는 아니다.
 -> not A 
(만약 True면)  -> False


(비교연산자, bool's 연산자 예시)



* 표준 입/출력 함수
 
 - print() -> 표준 출력장치로 내용을 출력하는 함수

 - input() -> 표준 입력장치로 내용을 입력하는 함수
  - 한줄을 입력받는다.
  - 괄호 안에 문자열을 적으면 입력받기 전에 문자열을 출력해준다.
  - input된 값은 무조건 문자열이 된다. 
     (만약 숫자로 받고싶으면  정수형, 혹은 실수형으로 형변환을 해야한다.

분기문 -> 분기점을 만들어줄 수 있는 문장. (실행 흐름 제어)

* 파이썬에서의 분기문
 if 사용법
 
 if expression :   
 
 콜론을 써줘야한다. 
 if expression :
  <if block>
  ...
  ...
 -> if block의 구분 방법 : 들여쓰기로 구분한다.

if - else 사용법
 if expression:
  <if block>
 else:
  <else block>
 -> 둘중에 하나만 실행된다. else는 if문장이 참이 아니면 else blck을 실행한다.
 
다중 if 사용법
 다중 블록
 if expression:
  <if block>
 elif expression:
  <elif block>
 else:
  <else block>

* 반복문
 
 while expression :
  <while block>
 -> 조건이 참일 때 반복된다.

* 멤버 메서드
 
 해당 객체가 제공해주는 함수.
 문자열도 하나의 객체처럼 다뤄진다.

 -> isalnum()
 -> isdigit()  : 문자열에 숫자만 있는지 확인해주는 함수.

* 반복문 혹은  if문으로 block을 묶을 때 들여쓰기 간격이 일정해야한다.

* 프로그램 이란?
 - 저장된 명령어들을 일괄적으로 실행하는 것이다.

이제 지금까지 배운 내용들로 프로그램을 작성해 볼 것이다.

만들어볼 프로그램은
온도변환 프로그램이다.

특징
- 대화식 프로그램이다. 사용자가 입력하면 그에 따라 컴퓨터는 출력한다.
- 사용자가 섭씨 온도를 입력하면 화씨 온도로 변경해서 출력해주는 프로그램
- 혹은 화씨 온도를 입력하면 섭씨 온도로 출력하는 프로그램

* 알고리즘
: 문제를 해결하는 과정으로 프로그램의 동작 과정을 먼저 생각해야한다.


(프로그램 코드)


(정상적으로 출력되는 화면)


+ Recent posts