Smail 문법
- return vAA
A: 목표 레지스터(8bits)
4byte까지의 데이터를 리턴합니다.
- return-object vAA
A: 목표 레지스터(8bits)
단순 변수가 아닌 Object를 리턴할 때 사용합니다.
- const/4 vA, #+B
A: 목표 레지스터(4bits), B: 정수(4bits)
B(4바이트까지 부호확장?)에 지정된 값을 A에 넣어 줍니다.
- const/16 vAA, #+BBBB
A: 목표 레지스터(8bits), B: 정수(16bits)
B(4바이트까지 부호확장?)에 지정된 값을 A에 넣어 줍니다.
- const vAA, #+BBBBBBBB
A: 목표 레지스터(8bits), B: 임의의 4바이트 상수
B에 지정된 상수 값을 A에 넣어 줍니다.
- const-string vAA, string@BBBB
A: 목표 레지스터(8bits), B: 문자열
B에 지정된 문자열에 대한 참조를 A에 넣어 줍니다.
- array-length vA, vB
A: 목표 레지스터(4bits), B: 배열 참조 레지스터(4bits)
B로 지정된 배열의 길이로 A에 저장합니다.
- new-array vA, vB, type@CCCC
A: 목표 레지스터(8bits), B: 사이즈 레지스터, C: 타입
C로 지정한 형식으로 B로 지정한 사이즈로 배열 A를 만듭니다.
- goto +AA
A: 분기할 오프셋(8bits)
무조건 A로 지정된 오프셋으로 분기합니다.
- if-.... vA, vB, +CCCC
A: 비교할 첫번째 레지스터(4bits), B: 비교할 두번째 레지스터(4bits)
C: 분기할 오프셋(16bits)
지정한 A, B 두 레지스터 값을 비교하여 C로 지정된 오프셋으로 분기합니다.
if-eq: A = B, if-ne: A != B(다르다), if-lt: A < B
if-ge: A >= B, if-gt: A > B, if-le: A <= B
- if-....z vAA, +BBBB
A: 비교할 레지스터(8bits), B: 분기할 오프셋(16bits), 주로 :cond_0
지정한 A 레지스터 값을 0과 비교하여 B로 지정된 오프셋으로 분기합니다.
if-eqz: A = 0, if-nez: A != 0(다르다), if-ltz: A < 0
if-gez: A >= 0, if-gtz: A > 0, if-lez: A <= 0
- invoke-.... {vC, vD, ...}, meth@BBBB
B: 참조할 함수, C,D,... 함수의 인수
B로 지정한 함수를 실행합니다.
결과는 위에서 설명한 move-result 로 받을 수 있습니다.
invoke-virtual, invoke-direct, invoke-static, ... 등이 있습니다.
- unop vA, vB
A: 목표 레지스터(4bits), B: 소스 레지스터(4bits)
소스 레지스터B로 단항연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
neg-int, neg-long, neg-float, neg-double: A = -B
not-int, not-long: A = ~B
int-to-long: int64 A = (int64) B; int32 B;
int-to-float: float A = (float) B; int32 B;
int-to-double: double A = (double) B; int32 B;
...
- binop vAA, vBB, vCC
A: 목표 레지스터(8bits),
B: 첫번째 소스 레지스터(8bits), C: 번째 소스 레지스터(8bits)
두 소스 레지스터 B, C로 부터 지정된 바이너리 연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
add-int, add-long, add-float, add-double: A = B + C
sub-int, sub-long, sub-float, sub-double: A = B - C
mul-int, mul-long, mul-float, mul-double: A = B * C
div-int, div-long, div-float, div-double: A = B / C
rem-int, rem-long, rem-float, rem-double: A = B % C (B/C의 나머지)
and-int, and-long: A = B & C (And)
or-int, or-long: A = B | C(Or)
xor-int, xor-long: A = B ^ C(Exclusive Or)
shl-int, shl-long: A = B << (C&0x1f) (Shift Left)
shr-int, shr-long: A = B >> (C&0x1f) (Shift Right)
ushr-int, ushr-long: A = B >> (C&0x1f) (Shift Right)(Unsigned)
- binop/2addr vA, vB
A: 목표+첫번째 소스 레지스터(4bits), B: 두번째 소스 레지스터(4bits)
소스 레지스터 A, B로 부터 지정된 바이너리 연산을 수행 후 첫번째 소스 레지스터A에 결과를 저장합니다.
add-int/2addr, add-long/2addr, add-float/2addr, add-double/2addr: A = A + B
sub-int/2addr, sub-long/2addr, sub-float/2addr, sub-double/2addr: A = A - B
mul-int/2addr, mul-long/2addr, mul-float/2addr, mul-double/2addr: A = A * B
div-int/2addr, div-long/2addr, div-float/2addr, div-double/2addr: A = A / B
rem-int/2addr, rem-long/2addr, rem-float/2addr, rem-double/2addr: A = A % B
and-int/2addr, and-long/2addr: A = A & B
or-int/2addr, or-long/2addr: A = A | B
xor-int/2addr, xor-long/2addr: A = A ^ B
shl-int/2addr, shl-long/2addr: A = A << (B&0x1f)
shr-int/2addr, shr-long/2addr: A = A >> (B&0x1f)
ushr-int/2addr, ushr-long/2addr: A = A >> (B&0x1f)(Unsigned)
- binop/lit16 vA, vB, #+CCCC
A: 목표 레지스터(4bits),
B: 소스 레지스터(4bits), C: 정수 상수(16bits)
소스 레지스터 B와 상수C로 부터 지정된 바이너리 연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
add-int/lit16: A = B + C
rsub-int: A = C - B (역 뺄샘)
mul-int/lit16: A = B * C
div-int/lit16: A = B / C
rem-int/lit16: A = B % C
and-int/lit16: A = B & C
or-int/lit16: A = B | C
xor-int/lit16: A = B ^ C
- binop/lit8 vAA, vBB, #+CC
A: 목표 레지스터(8bits),
B: 소스 레지스터(8bits), C: 정수 상수(8bits)
소스 레지스터 B와 상수C로 부터 지정된 바이너리 연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
add-int/lit8: A = B + C
rsub-int/lit8: A = C - B (역 뺄샘)
mul-int/lit8: A = B * C
div-int/lit8: A = B / C
rem-int/lit8: A = B % C
and-int/lit8: A = B & C
or-int/lit8: A = B | C
xor-int/lit8: A = B ^ C
A: 목표 레지스터(8bits)
4byte까지의 데이터를 리턴합니다.
- return-object vAA
A: 목표 레지스터(8bits)
단순 변수가 아닌 Object를 리턴할 때 사용합니다.
- const/4 vA, #+B
A: 목표 레지스터(4bits), B: 정수(4bits)
B(4바이트까지 부호확장?)에 지정된 값을 A에 넣어 줍니다.
- const/16 vAA, #+BBBB
A: 목표 레지스터(8bits), B: 정수(16bits)
B(4바이트까지 부호확장?)에 지정된 값을 A에 넣어 줍니다.
- const vAA, #+BBBBBBBB
A: 목표 레지스터(8bits), B: 임의의 4바이트 상수
B에 지정된 상수 값을 A에 넣어 줍니다.
- const-string vAA, string@BBBB
A: 목표 레지스터(8bits), B: 문자열
B에 지정된 문자열에 대한 참조를 A에 넣어 줍니다.
- array-length vA, vB
A: 목표 레지스터(4bits), B: 배열 참조 레지스터(4bits)
B로 지정된 배열의 길이로 A에 저장합니다.
- new-array vA, vB, type@CCCC
A: 목표 레지스터(8bits), B: 사이즈 레지스터, C: 타입
C로 지정한 형식으로 B로 지정한 사이즈로 배열 A를 만듭니다.
- goto +AA
A: 분기할 오프셋(8bits)
무조건 A로 지정된 오프셋으로 분기합니다.
- if-.... vA, vB, +CCCC
A: 비교할 첫번째 레지스터(4bits), B: 비교할 두번째 레지스터(4bits)
C: 분기할 오프셋(16bits)
지정한 A, B 두 레지스터 값을 비교하여 C로 지정된 오프셋으로 분기합니다.
if-eq: A = B, if-ne: A != B(다르다), if-lt: A < B
if-ge: A >= B, if-gt: A > B, if-le: A <= B
- if-....z vAA, +BBBB
A: 비교할 레지스터(8bits), B: 분기할 오프셋(16bits), 주로 :cond_0
지정한 A 레지스터 값을 0과 비교하여 B로 지정된 오프셋으로 분기합니다.
if-eqz: A = 0, if-nez: A != 0(다르다), if-ltz: A < 0
if-gez: A >= 0, if-gtz: A > 0, if-lez: A <= 0
- invoke-.... {vC, vD, ...}, meth@BBBB
B: 참조할 함수, C,D,... 함수의 인수
B로 지정한 함수를 실행합니다.
결과는 위에서 설명한 move-result 로 받을 수 있습니다.
invoke-virtual, invoke-direct, invoke-static, ... 등이 있습니다.
- unop vA, vB
A: 목표 레지스터(4bits), B: 소스 레지스터(4bits)
소스 레지스터B로 단항연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
neg-int, neg-long, neg-float, neg-double: A = -B
not-int, not-long: A = ~B
int-to-long: int64 A = (int64) B; int32 B;
int-to-float: float A = (float) B; int32 B;
int-to-double: double A = (double) B; int32 B;
...
- binop vAA, vBB, vCC
A: 목표 레지스터(8bits),
B: 첫번째 소스 레지스터(8bits), C: 번째 소스 레지스터(8bits)
두 소스 레지스터 B, C로 부터 지정된 바이너리 연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
add-int, add-long, add-float, add-double: A = B + C
sub-int, sub-long, sub-float, sub-double: A = B - C
mul-int, mul-long, mul-float, mul-double: A = B * C
div-int, div-long, div-float, div-double: A = B / C
rem-int, rem-long, rem-float, rem-double: A = B % C (B/C의 나머지)
and-int, and-long: A = B & C (And)
or-int, or-long: A = B | C(Or)
xor-int, xor-long: A = B ^ C(Exclusive Or)
shl-int, shl-long: A = B << (C&0x1f) (Shift Left)
shr-int, shr-long: A = B >> (C&0x1f) (Shift Right)
ushr-int, ushr-long: A = B >> (C&0x1f) (Shift Right)(Unsigned)
- binop/2addr vA, vB
A: 목표+첫번째 소스 레지스터(4bits), B: 두번째 소스 레지스터(4bits)
소스 레지스터 A, B로 부터 지정된 바이너리 연산을 수행 후 첫번째 소스 레지스터A에 결과를 저장합니다.
add-int/2addr, add-long/2addr, add-float/2addr, add-double/2addr: A = A + B
sub-int/2addr, sub-long/2addr, sub-float/2addr, sub-double/2addr: A = A - B
mul-int/2addr, mul-long/2addr, mul-float/2addr, mul-double/2addr: A = A * B
div-int/2addr, div-long/2addr, div-float/2addr, div-double/2addr: A = A / B
rem-int/2addr, rem-long/2addr, rem-float/2addr, rem-double/2addr: A = A % B
and-int/2addr, and-long/2addr: A = A & B
or-int/2addr, or-long/2addr: A = A | B
xor-int/2addr, xor-long/2addr: A = A ^ B
shl-int/2addr, shl-long/2addr: A = A << (B&0x1f)
shr-int/2addr, shr-long/2addr: A = A >> (B&0x1f)
ushr-int/2addr, ushr-long/2addr: A = A >> (B&0x1f)(Unsigned)
- binop/lit16 vA, vB, #+CCCC
A: 목표 레지스터(4bits),
B: 소스 레지스터(4bits), C: 정수 상수(16bits)
소스 레지스터 B와 상수C로 부터 지정된 바이너리 연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
add-int/lit16: A = B + C
rsub-int: A = C - B (역 뺄샘)
mul-int/lit16: A = B * C
div-int/lit16: A = B / C
rem-int/lit16: A = B % C
and-int/lit16: A = B & C
or-int/lit16: A = B | C
xor-int/lit16: A = B ^ C
- binop/lit8 vAA, vBB, #+CC
A: 목표 레지스터(8bits),
B: 소스 레지스터(8bits), C: 정수 상수(8bits)
소스 레지스터 B와 상수C로 부터 지정된 바이너리 연산을 수행 후 목표 레지스터A에 결과를 저장합니다.
add-int/lit8: A = B + C
rsub-int/lit8: A = C - B (역 뺄샘)
mul-int/lit8: A = B * C
div-int/lit8: A = B / C
rem-int/lit8: A = B % C
and-int/lit8: A = B & C
or-int/lit8: A = B | C
xor-int/lit8: A = B ^ C