4. BYTES
컴퓨터에서 처리되는 모든 것은 byte의
흐름(Stream)
(File)
0x03, 0x22, 0x00, 0x3a, …
(Memory)
0xff, 0xdf, 0x32, 0x4a, …
(Network Data)
0x9d, 0x34, 0x05, 0x80, …
5. 그럼 어떤 데이터를 어떻게
구분해서 사용할 수 있지?
-> 미리 약속된 DATA FORMAT에
따라 입출력하게 됨
(NETWORK의 경우
프로토콜이라고 불림)
6. FILE FORMAT
• 8 byte짜리 파일 “what.dat”
“0x04, 0x68, 0x9f, 0x6f, 0x79, 0x0a, 0xc8,
0x55”
• Format 을 모르면 무용지물
• short(2), int(4), byte(1), byte(1) 일
수도
• Double(8) 일 수도
• 단지 String일 수도 있음(text file)
• 기본적으로 문자 코드(Ascii code, UTF-8,
EUC-KR, …)로만 이루어져 있으면
텍스트 파일, 그 외에는 바이너리
파일이라고 보면 됨.
• 에디터에서 잘 보이면 텍스트 파일 _-
7. FILE FORMAT
• 확장자로 파일을 구분하는 것은 „사람‟을
위한 것
• 누가 야동 파일 확장자를 avi에서 hwp로
바꿔 놓으면 어떻게 암?
• 군대에서 영창 갈 뻔…
• 리눅스/유닉스에서는 (주로 알려진) 파일
포맷을 검사하는 file이란 툴 존재
10. ASSEMBLY
• 컴퓨터는 기계어를 이해한다.
• 기계어를 처리하는 것은 CPU다.
• CPU는(32비트 기준) 극단적으로 말해
스위치 32개를 가진 회로이다.
• 즉 이 32개의 스위치 -> 32개의
비트(4바이트)를 어떤 방식으로 켜고
끄느냐에 따라 CPU가 하는 일이
달라진다.
11. ASSEMBLY
• 즉 CPU는 순서대로 들어오는 기계어
명령을 곧이 곧대로 처리할 뿐, 변수니
함수니 메써드니 클래스니 하는 개념
따위는 전혀 없다.
• 예 : 2+3을 실행하면 컴퓨터는 다음과
같이 처리함
1. Stack에 2 저장.
2. Stack에 3 저장.
3. Stack에서 숫자 두 개 빼서 더한 후
결과를 다시 stack에 저장
4. Stack에서 pop -> 결과는 5
12. BYTECODE
• JVM Bytecode도 실행 원리는
어셈블리와 동일.
• Bytecode와 stack과 „정해진 갯수‟의 임시
변수만 갖고 모두 처리
• 우리가 쓰는 Java Code는 „사람이 보기
편한‟ 형태일 뿐. 사실은 한 마디로
말해서 C든 Java든 죄다 컴퓨터가 이해
못하는 언어임.
13. WHY
BYTECODE?
• (복잡해 보이겠지만) 구현이 간단함.
• CPU가 처리하는 어셈블리 코드랑
형태가 비슷
• 계산기를 프로그래밍한다고 생각해
보면 ,
• 예 : 3+4*2-1
• 한 번에 계산식을 읽으면서
중간중간 계산 해서 최종 결과를
내는 방식도 있겠지만
• 계산식이 복잡해질 수록
• 4*2 -> (a)
• 3 + (a) -> (b)
• (b) – 1
• 이런 식으로 작은 수식으로
분해(혹은 트리구조 분해)해서
각각의 계산을 처리하는 방식이
훨씬 용이
• 처음 식이 Java code라면 작은
수식들이 바이트코드인 셈
15. COMPILE?
• Source code를 기계어 파일 –
실행파일이나 라이브러리로 번역하는
과정
• 컴파일의 과정
• Tokenizing
• Syntax parsing
• Optimization
• Code Generation
16. TOKENIZING
• 언어에 정의된 각각의 토큰을 체크하는
과정
• if ( a >= 1) continue;
->
• IF, LP, STR, GTR, NUM, RP, CONTINUE,
SEMICOL
17. PARSING
• 각 토큰들이 문법에 맞게 제대로
배치되었는지 확인
• IF, LP, STR, GTR, NUM, RP, CONTINUE,
SEMICOL
• 예)
• if 다음엔 반드시 왼쪽 괄호가 오므로
LP가 아닌 경우 에러
• >= 다음엔 숫자 외에도 변수, 메써드
등이 올 수 있으므로 NUM이 아닌
경우에도 무조건 에러가 나오진
않음. 하지만 바로 오른쪽 괄호가
온다면 에러
19. OPTIMIZATION
• 말 그대로 코드 최적화
• 예)
• For문 100만번 도는데 안에 a=1
밖에 없다. -> for문 삭제
• If (a > 0 && a > 1) -> 왼쪽 조건 삭제
• 이런 것들은 SQL 실행시에 DBMS에서도
수행함
• 사람보다 낫다 -_-
21. Magic number(4)
OVERALL
FORMAT
Minor version(2)
Major version(2)
Constant pool
Access flags(2)
This class(2)
Super class(2)
Interface information
Field information
Method information
Attributes
• (n) = n bytes
• 숫자가 없는 필드들은 사이즈
가변적, 즉 실제 코드와 비례해서
많아지는 데이터들
22. HEADER
• Magic Number : class 파일임을
나타내는 특정 숫자. 무조건
0xCAFEBABE의 값을 가짐.
• Major, Minor version : 클래스 파일 포맷
버전.
• Constant pool : 문자열 상수 및 클래스
이름, 메써드 이름 등의 정보를 가짐.
• Access flags : 클래스 접근 권한
• This class, super class : 현재 클래스와
부모 클래스 이름 및 정보. Constant
pool의 인덱스 번호임
26. 전체 POOL 구성
CONSTANT
POOL
Constant Pool Count(2)
Constant Info #1
Constant Info #2
…
Constant Info #n
각 Constant Info 구성
tag(1)
(constant type 표시)
data
(tag에 따라 사이즈 다름)
28. • 하지만 그냥 넘어가면 서운하니 몇
가지만…
CONSTANT
INFO
CONSTANT_Methodref_Info
tag(1)
class index(2) -> CP
Name and type index(2) -> CP
CONSTANT_Class_Info
tag(1)
name index(2) -> CP
CONSTANT_Utf8_Info
tag(1)
length(2)
Utf8 string (length)
30. CONSTANT
IFNO
• 복잡해 보이지만 파일 사이즈를
줄이려면 최대한 중복을 줄여야 하니
어쩔 수 없음.
• Database 설계 및 사용시 중복 데이터를
줄이기 위해 정규화를 하고 각종
테이블로 나눠놓고 또 복잡하게 foreign
key 참조해서 join해서 불러다 쓰고 하는
걸 경험해 본 분들도 계실텐데 결국 같은
사상을 깔고 있는 것임.
31. THIS CLASS,
SUPER CLASS
• 각 2바이트를 차지하는 것에서 유추
가능하듯, 이 부분은 따로 정보를 갖고
있는게 아니라 각각 Constant Info의 해당
Class Info 번호를 가리킴
32. INTERFACE
INFO
Interface Count(2)
Interface Info #1 (2)
Interface Info #2 (2)
…
Interface Info #n (2)
• 이 클래스가 구현하는 인터페이스
정보들
• 첫번째 2바이트는 인터페이스 갯수를
의미하며, count 수만큼 각 2바이트의
인터페이스 정보를 가리키는 constant
pool 인덱스가 있다.
• 즉, this class, super class와 같은 방식.
33. Field Info 전체 구성
FIELD INFO
Field Count(2)
Field Info #1
Field Info #2
…
Field Info #n
각 Field Info 구성
• 클래스가 갖고 있는 필드 –
인스턴트 변수 및 클래스
변수- 에 대한 정보.
Access flags(2)
Name index(2) -> CP
Descriptor index(2) -> CP
Attribute count(2)
Attributes[count]
35. Method Info 전체 구성
METHOD INFO
Method Count(2)
Method Info #1
Method Info #2
…
Method Info #n
각 Method Info 구성
• 클래스가 갖고 있는
인스턴트 메써드 및
클래스 메써드에 대한
정보.
• 필드 정보와 구성 동일
Access flags(2)
Name index(2) -> CP
Descriptor index(2) -> CP
Attribute count(2)
Attributes[count]
37. ATTRIBUTE
• 클래스, 메써드, 필드의 기본
정보(접근 권한, 타입 등) 이외에
추가적인 속성에 대한 정보가
기록됨
• 속성이 속성을 또 가질 수 있음.
• 속성이란 단어를 쓰지만 필수적인
정보들도 있음
- 예를 들어 메써드 같은 경우는
Code란 속성이 필수적이며
Code는 LineNumberTable,
LocalVariableTable에 대한
속성이 있음.
38. Attribute Name Index (2)
Attribute Length (4)
ATTRIBUTE
Attribute Data
Attribute Name에 따라 Data
구성은 다름
종류(Name)
의미
ConstantValue
상수값
Code
메써드의 바이트코드
Exceptions
예외들
InnerClasses
내부 클래스
Synthetic
SourceFile
소스 파일 정보
LineNumberTable
바이트 코드와
매칭되는 실제 소스
코드 라인번호
LocalVariableTable
지역변수 정보
Deprecated
40. Method Info
Access flags : public
Name : minus
METHOD
DECOMPILE
EXAMPLE
Type : (II)I
Max stack : 2
Max local : 3
Code:
0x1B
0x1C
0x64
0xAC
LineNumberTable
Start
PC
Line
0
7
LocalVariableTable
Start
PC
Length Name
Type
Index
0
4
this
Lmy/test/Test;
0
0
4
a
I
1
0
4
b
I
2
41. METHOD
DECOMPILE
EXAMPLE
(CODE 설명)
• 0x1B (iload_1)
-> local 변수 1을 스택에 로드
• 0x1C (iload_2)
-> local 변수 2를 스택에 로드
• 0x64 (isub)
-> stack에서 두 개의 아이템을 꺼내
뺄셈하고 결과를 다시 stack에 넣음
• 0xAC (ireturn)
-> stack의 아이템을 메써드 결과값으로
리턴
46. METHOD
DECOMPILE
EXAMPLE
#5
• 메써드 정보에서 이 메써드의 이름이나
타입을 모두 알 수 있음.
• 메써드 signature와
LocalVariableTable를 비교해서 인자
변수 이름도 모두 파악 가능
• LineNumberTable과 대조해 보면 한
줄짜리 메써드라는 것이 파악됨.
결과) my.test.Test 클래스 안의 7번째
라인의 minus 메써드.
public int minus(int a, int b) { return a-b;}
47. REFERENCES
• Java VM spec : http://goo.gl/52JCW
• Wikipedia Bytecode Instruction :
http://goo.gl/pncN9
• Demo Code :
https://code.google.com/p/javaseminar/