/*
written by kaspy (kaspyx@gmail.com)
*/
문득 어셈블리 언어를 보다보면 자주쓰지 않는 만큼 해깔릴수 있는것들이 많은것 같아서 정리해보았다. 특히 주소 연산 mov [100], 10 같은것들
많이 사용되지 않는 16bit 어셈블리어지만 레지스터 크기나 명령어 이름만 조금 바꾼 형태로 익힌다면 32bit도 그리 어렵지는 않을것이다.
이번에는 비교 및 분기문, 특수연산 등으로 정리하였다.
JG 및 JA 명령어
예제)
- mov bl, 5
- cmp al, bl
- jg 0188
- ja 018a
- ;bl 레지스터에 5를 저장하고 al과 비교하여 클 경우 018a 주소로 번지시킵니다.
- ;여기서 jg 구문에서 점프하지 않고 ja에서 한 이유는 jg는 부호있는 검사를 하여 al의 값은 음수가 됩니다.
- ;이때는 al이 bl 보다 작으며 ja 로 비교했을 경우는 부호없는 비교이기 때문에
- ;al은 ff로 비교하게되고 참이기 때문에 018a 번지로 점프합니다.
JL 명령어
예제)
- cmp al, bl
- jl 198
- ;al과 bl을 비교하여 al이 작을 경우 198번지로 이동합니다.
- ;jl 은 부호있는 음수로 비교하기 때문에 al레지스터는 ff가 아니라 -7f입니다.
- ;bl = 5 이기 때문에 작다는 조건을 만족하고 198번지로 이동합니다.
JL JA JG 명령어
예제)
- cmp al, bl
- jl 01aa
- ja 01ac
- jg 01ae
- ;al과 bl을 비교해서 참값이 되면 해당번지로 점프시킵니다.
- ;여기서 jl 은 부호있는 비교이기 때문에 bl은 ff가 아니라 -7f이고 al은 5이기 때문에 조건을 만족하지 않습니다.
- ;ja는 부호없는 비교이며 이때는 bl이 ff이므로 조건을 만족하지 않아 점프하지 않고
- ;jg는 부호있는 비교이므로 al은 5 그리고 bl은 -7f 와 비교하여 al이 더크기 때문에 1ae번지로 점프합니다.
LOOP 명령어
예제)
- mov cx, 8
- inc ax
- loop 01b6
- ;cx레지스터가 0이 될 때까지 감소 시키면서 (loop)01b6 번지를 반복합니다.
- ;01b6번지는 inc ax이며 8번 반복하여 ax가 8이 되었습니다.
SHR 명령어
예제)
- shr bh, 1
- ;bh 레지스터를 오른쪽으로 1만큼 쉬프트 연산합니다.
AND, NOT, OR, XOR 명령어
예제)
- and al, bl
- not al
- or al, bl
- xor al, bl
- ;해당 레지스터와 al <- al 연산 bl
- ;논리연산 and, not, or, xor를 수행합니다.
- ;not은 1이면 0으로 0은 1로 바꿉니다.
LODSB 명령어
예제)
- lodsb
- ;ax의 하위 1바이트 al 레지스터에 ds 세그먼트 오프셋 si 의 값을 저장합니다. 즉
- ;al <- ds:si
REPZ, STOSW 명령어
예제)
- mov cx, 07d0
- repz
- stosw
- ;cx에 07d0를 저장하고 repz 와 stosw를 실행하면 cx레지스터를 0이 될 때까지 1씩 감소시키며
- ;반대로 di는 2byte(1word) 증가시키며 ax의 값을 es:di 의 주소값에에 복사를 합니다.
- ;es의 b800 주소값은 Video ram이 시작되는 부분으로 여기의 값을 수정하면 화면을 제어할수 있습니다.
- ;es:0000부터 es:0fa0 까지 20과 07을 저장합니다.
명령어 응용
예제)
- lea si, arr1
- mov di, 160*10 + 2*30
- lp: lodsb
- mov ah, 7
- stosw
- loop lp
- ;arr1은 "hello" 라는 문자열이 저장되어있는 있음
- ;si에 arr1배열의 시작주소를 si에 넣고 160 *10 + 2*30 (화면의 정중앙)의 값을 di에 저장합니다.
- ;lodsb를 하면 ds:si 의 값을 al에 1byte 저장하고 ah에는 7을 저장합니다. 그리고
- ;stosw를 하면 문자열 hello문자열을 차례대로 가져와서 stosw를 통해 화면의 정중앙에 문자열을 출력해줍니다.
- ;이상하게 es:di 의 값이 stosw을 통해 의도적으로 바뀌지 않았는데 이는 화면이 수시로 바뀌는 특성 때문에 그런거 같습니다.
- ;또한 메모리 시작주소 b800h 영역은 프롬프트상에서 비디오 출력 메모리 공간임을 추측할수 있었습니다.
추가**
- mov ah, 9
- int 21h
- ; 이명령을 추가로 실행시켜주면 아래와 같은 문자열이 출력됨
* 관련 링크 참조
http://kaspyx.tistory.com/entry/16bit-Assembly-예제-정리-1
'IT > Intel 16bit Assembly' 카테고리의 다른 글
x86 16bit 어셈블리(Assembly) 예제 정리 - 3 (0) | 2015.04.09 |
---|---|
x86 16bit 어셈블리(Assembly) 예제 정리 - 2 (0) | 2015.04.09 |
x86 16bit 어셈블리(Assembly) 예제 정리 - 1 (0) | 2015.04.08 |