농소
asm 형변환, 관계연산, 제어문 본문
형변환
1). 큰 -> 작은 저장소 ( 큰 문제는 없다. )
int a = 10
short b =a
ex) eax -> ax -> al
별다른 명령어가 필요하지않고 해당 레지스터 크기를 줄여서 사용
하지만 줄이는과정에 상위비트의 값의 손실이 발생할 수 있음.
2). 작은 -> 큰
short a =10
int b = a
예를들어 8비트 크기의 레지스터인 dl 값을 16비트인 ax로 옮길려고 할시 컴파일 에러가 발생한다.
바로 8비트를 채우고 나머지 8비트를 무엇으로 채워야 할지 모르기 때문이다.
그것을 해결하기 위해선
[ movzx ( zero extend - 나머지를 0으로 채우겠다.) ]
[ movsx ( sign extend - 부호가 있는경우 음수일 때 나머지 빈공간을 1로 채우겠다. ]
이 두 명령어가 필요한데 movzx는 나머지 비트들을 0으로 채우고
movsx는 만약 값이 음수일때 부호까지 신경써서 나머지 비트를 채운다
< mov 와 movzx 비교 >
< mov eax, dl 을 했을때 에러가 발생하는 모습 >
< -10일때 부호까지 신경써주는 movsx명령어를 사용 >
만약 movzx명령어를 사용하면 나머지 비트에 0을 채우게 되므로 -10이 아닌 값이 246이 나오게 된다.
즉, 0으로 채워서 0000 0000 1111 0110 = 246이 나오게 된다.
그러니 부호까지 신경쓰는 movsx를 쓰면 나머지 8bit도 1로 채우므로 1111 1111 1111 0110 = 10이 나온다
3). 논리쉬프트 shl, shr
xor edx, edx
mov dl, -2
shl dl, 2
shr dl, 2
-2가 나와야하지만 62가 출력됨
그래서 산술쉬프트 sal, sar 연산을 해야함
비교연산
- cmp : compare
- cmp vleft, vright -> eflags register
연산과정을 보면 Sub명령어와 구조가 매우 흡사하다.
여기서 vleft, vright의 뺄셈을 통해 부호가 정수이면 SF = 0 ZF =0
음수 SF = 1 ZF =0
같다면 SF = 0 ZF =1이 된다.
여기서 SF, ZF란? FLAG REGISTER의 여러 FLAG중에 하나이다.
SF는 Sign Flag의 약어로 비교연산을 했을시 부호가 변하면 1 아니면 0 으로 표현되고
ZF는 Zero Flag의 약어로 비교연산을 했을시 값이 같다면 1 다르다면 0으로 표현된다.
cmp는 sub과 구조가 매우 흡사하나 차이점이 존재한다 cmp는 sub과는 다르게
- 1. 특정 메모리나 레지스터의 값을 변경하지 않는다.
- 2. [ 플래그 레지스터 ] 에 반영한다!!
즉, sub명령어는 레지스터값에 영향을 주고 cmp는 영향을 주지 않는다.
오로지 cmp는 flag 레지스터에만 영향을 줌.
이 해당 SF,ZF만 확인할수 있는 방법은 nasm에서 명령어로 존재하지 않아.
eflags register 전체를 볼 수 있는 명령어를 통해서 확인 해보겠다.
<pushfd 명령어로 flag 상태를 확인함>
< 10진수로 flag의 상태를 보여줌 >
< 2진수로 변환한 모습 >
자 flag register의 구조를 보면 하위7비트에 ZF 하위 8비트에 SF가 위치해 있다.
10 과 5를 비교할때 연산과정을 보면 10 - 5 = 5 (양수)가 나온다 양수일때는 SF = 0 , ZF = 0이 되므로
2진수를 봤을때 0000 0010 [00]00 0110 으로 표현된다.
만약 음수였으면 00이 아니라 10이 되었을 것이다.
제어문: if, case
- if, case는 기계어로보면 동일하게나옴.
- 그래서 어셈블 코드를 분석할 때 if인지 case인지 구분할 수 없음.
- 즉, if, case는 아무 차이없고, for,while도 차이없음.
1). 무조건 분기: jmp(jump) 강제 이동한다.
C언어로 치자면 goto문으로 생각하면된다
- jmp 주소 - [ 지금은 이것을 이용 ]
- jmp offset
주소를 설정하여 해당 주소로 강제로 이동시킬수 있는 표현방법이다.
강제로 end주소로 이동하게 되어 print문을 건너뛰게 된다.
2). 조건 분기 : 조건을 확인하고 이동한다
- j<조건>
.
.
.
등 여러 조건이 많지만 외워서 쓸 필요는 없고 직관적으로 표현되어서 쉽게 사용할 수 있다.
jg(great) = 크다 je = 같다(equal) jl = 작다(less)
실습 - c언어로 표현한것을 어셈블로 표현하라.
c언어
if ( a < 10 ) {
printf("less then 10\n");
} else {
printf("bigger then 10\n");
}
3). 다중조건
실습2 - and와 or가 섞여있는 경우
if( ( a < 10 && b > 1 ) || c == 5) {
printf("correct\n");
}
'Security > System Hacking' 카테고리의 다른 글
nasm 반복문 연습2 (0) | 2018.01.20 |
---|---|
nasm 반복문 연습 (0) | 2018.01.19 |
어셈블리 사칙연산(ADD, SUB, MUL, IMUL, DIV, IDIV), 비트연산, 논리연산 (0) | 2018.01.17 |
레지스터, INTEL 명령어 (0) | 2018.01.16 |
3. ELF파일 구조, nasm 데이터표현 (0) | 2018.01.13 |