형변환
1). 큰-> 작은
int a = 10
short b = a
2). 작은 -> 큰
short a = 10
int b = a
movzx//부호가 없는경우 확장
movsx//부호가 있는 경우 확장
음수 표현법
0000 0001
1111 1110(1의 보수)
1111 1111(2의 보수) = -1이다.
어셈블리는 C와 다르게 작은값에서 큰값으로 넘어갈때 형변환이 필요하다
extern printf
segment .data
prompt_int db '%d',10,00
prompt_int_int db '%d %d',10,10
a dw 9876
segment .bss
result resd 1
segment .text
global main
main:
mov dx, 10
movzx eax, dx
관계 연산: >, <, =, <=, >=, !=
-cmp(compare)
-cmp vleft, vright ->eflags register
-sub vleft, vright ,
! 메모리나 레지스터의 값을 변경하지 않는다.
! 플래그 레지스터에 반영
1). vleft가 큰 경우:양의 정수
-SF: 0, ZF: 0 -부호도 발생하지 않고 제로도 아니니까 둘다 00
2). vright가 큰경우:음의 정수
-SF: 1, ZF:0 -부호가 발생하고 제로는 아니니까 SF만 1 ZF 는 0
3). 같은 경우: 0
-SF: 0, ZF: 1 -부호가 발생하지 않고 제로니까 SF:0 ZF:1
ex)
extern printf
segment .data
prompt_int db '%d',10,00
prompt_int_int db '%d %d',10,10
a dw 9876
segment .bss
result resd 1
segment .text
global main
main:
mov eax, 20
cmp eax, 20
pushfd
push prompt_int
call printf
SF,ZF를 확인 할 수 있는 방법은 pushfd 를 확인하고 계산기에서 자릿수를 확인한다
EFLAGS Register
Sign Flag(SF) -8번
Zero Flag(ZF) -7번
제어문: if, case (기계어 에서는 차이가 없다)
1). 무조건 분기:jmp
-jmp 주소
-jmp offset
ex)
extern printf
segment .data
prompt_int db '%d',10,00
prompt_int_int db '%d %d',10,10
hello1 db 'first step', 10, 00
hello2 db 'second step',10, 00
segment .bss
result resd 1
segment .text
global main
main:
jmp second
push hello1
call printf
second:
push hello2
call printf
2). 조건 분기
조건분기 종류를 살펴보면
- 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
...
if (a < 10) {
printf("less then 10\n");
}
ex)
extern printf
extern scanf
segment .data
prompt_int db '%d',10,00
prompt_int_int db '%d %d',10,10
string db 'less then', 10, 00
input db '%d',00
segment .bss
buffer resd 1
segment .text
global main
main:
push buffer
push input
call scanf
cmp dword [buffer],10 ;입력받은 결과와 10을 비교하고
jl if ;입력 받은 결과가 작으면 if 블록으로 이동하고
jmp end ;입력받은 결과가 크면 end로 무조건 분기한다
if: push string
call printf
end:
ex)-같은 결과인데 좀더 합리적으로 표현해보면
extern printf
extern scanf
segment .data
prompt_int db '%d',10,00
prompt_int_int db '%d %d',10,10
string db 'less then', 10, 00
input db '%d',00
segment .bss
buffer resd 1
segment .text
global main
main:
push buffer
push input
call scanf
cmp dword [buffer],10
jge end ;크거나 같으면 end로 간다
push string ;작으면 string이 출력된다.
call printf
end:
조건 분기 if else 같이 사용해서
if (a < 10) {
printf("less then 10\n");
}else {
printf("bigger then 10\n");
}
extern printf
extern scanf
segment .data
prompt_int db '%d',10,00
prompt_int_int db '%d %d',10,10
string1 db 'less then', 10, 00
string2 db 'bigger then', 10, 00
input db '%d',00
segment .bss
buffer resd 1
segment .text
global main
main:
push buffer
push input
call scanf
cmp dword [buffer],10 ; cmp dword [buffer], 9
jge else ; jg else
then:
push string1
call printf
jmp end
else:
push string2
call printf
end:
3). 다중 조건
if( a< 10 && b > 1 && c == 5) {
printf("correct\n");
}
알고리즘
1.첫번째가 거짓이면 종료
2.첫번째가 참이면 두번째 조건까지 비교 거짓이면 종료
3.첫번째 두번째 조검이 참이면 세번째 조건까지 비교하고 거짓이면 종료
extern printf
extern scanf
segment .data
prompt_int db 'correct',10,00
prompt_int_int db '%d %d %d',10,10
input db '%d',00
string1 db 'a:%d',10,00
string2 db 'b:%d',10,00
string3 db 'c:%d',10,00
segment .bss
a resd 1
b resd 1
c resd 1
segment .text
global main
main:
push a
push input
call scanf
push b
push input
call scanf
push c
push input
call scanf
cmp dword [a],10
jl then
jmp end
then:
cmp dword [b] ,1
jg else
jmp end
else:
cmp dword [c],5
je else1
jmp end
else1:
push prompt_int
call printf
end:
다중 조건 2
if( a< 10 || b > 1 || c == 5) {
printf("correct\n");
}
extern printf
extern scanf
segment .data
prompt_int db 'correct',10,00
prompt_int_int db '%d %d %d',10,10
input db '%d',00
string1 db 'a:%d',10,00
string2 db 'b:%d',10,00
string3 db 'c:%d',10,00
segment .bss
a resd 1
b resd 1
c resd 1
segment .text
global main
main:
push a
push input
call scanf
push b
push input
call scanf
push c
push input
call scanf
cmp dword [a],10
jl else1
then:
cmp dword [b],1
jg else1
else:
cmp dword [c],5
je else1
jmp end
else1:
push prompt_int
call printf
end:
다중 조건 3
if( (a< 10 && b > 1) || c == 5) {
printf("correct\n");
}
알고리즘
1.A가 참이면 correct
1). a가 거짓이면 end
2). a가 참이고 b도 참이면 A가 참
2.A도 거짓 B도 거짓이면 end
else1은 A가 참일때 분기 하는곳
else 는 A가 거짓일때 분기하는 곳
else1 컬렉트를 출력하는 경우
end A,B 둘다 거짓일때
extern printf
extern scanf
segment .data
prompt_int db 'correct',10,00
prompt_int_int db '%d %d %d',10,10
input db '%d',00
string1 db 'a:%d',10,00
string2 db 'b:%d',10,00
string3 db 'c:%d',10,00
segment .bss
a resd 1
b resd 1
c resd 1
segment .text
global main
main:
push a
push input
call scanf
push b
push input
call scanf
push c
push input
call scanf
cmp dword [a] ,10
jl then
jmp else
then:
cmp dword [b] ,1
jg else1
jmp else
else:
cmp dword [c],5
je else1
jmp end
else1:
push prompt_int
call printf
end:
'시스템 해킹' 카테고리의 다른 글
[시스템 해킹] 어셈블리 함수 표현 (Stack) (0) | 2018.01.23 |
---|---|
[시스템 해킹] 어셈블리 반복문 (0) | 2018.01.18 |
[시스템 해킹] 어셈블리 사칙연산 (0) | 2018.01.16 |
[시스템 해킹] 주소 Vs 메모리,레지스터 (0) | 2018.01.15 |
[시스템 해킹] 어셈블리 언어(레이블,변수)표현법 (0) | 2018.01.12 |