아래 나온 것들만 알아도 어셈블리 프로그래밍 혹은 리버싱하는 데에 있어서
기초는 된 거임. 책을 보든 검색을 하든 아래의 내용들은 반드시 알아둘 것.
16-bit Assembly
- 레지스터
AX(AH:AL), BX(BH:BL), CX(CH:CL), DX(DH:DL)
SI, DI, SP, BP
IP, FLAGS
CS, DS, SS, ES
및 FLAGS의 각 플래그들의 의미
- 논리 주소와 물리 주소의 관계
(Segment:Offset ↔ Physical Address)
- 명령어
데이터 이동: MOV, LEA, LDS, LES, LSS, MOVZX/MOVSX
데이터 교환: XCHG
산술 연산: ADD/ADC/INC, SUB/SBB/DEC, MUL/IMUL, DIV/IDIV, NEG, CMP
비트 연산: AND, OR, XOR, NOT, SHL/SAL, SHR/SAR, ROL, ROR, TEST
문자열 관련: MOVS, CMPS, STOS, LODS, SCAS
반복 관련: LOOP/LOOPZ/LOOPNZ, REP prefix
실행 흐름 분기: JMP, Jcond/JNcond(조건 분기), CALL/RET, CALL FAR/RETF, INT/IRET
스택 조작 명령: PUSH/POP, PUSHA/POPA, PUSHF/POPF
스택 프레임 관련: ENTER, LEAVE
플래그 레지스터 관련: STC/CLC, STO/CLO, STI/CLI, SAHF, SETC/SETNC, SETO/SETNO, SETP/SETNP
특수 명령: NOP
- x87 부동 소수점 명령어
FLD, FST/FSTP, FADD/FADDP, FSUB/FSUBP, FMUL/FMULP, FDIV/FDIVP, FSQRT, FABS, ...
32-bit Assembly
- 레지스터 크기의 변화
EAX(16bit:AX), EBX(16bit:BX), ECX(16bit:CX), EDX(16bit:DX),
ESI(16b:SI), EDI(16b:DI), ESP(16b:SP), EBP(16b:BP)
EIP(16b:IP), EFLAGS(16b:FLAGS)
- 세그먼트 레지스터의 추가
FS, GS
- 명령어의 추가
PUSHAD/POPAD, PUSHFD/POPFD
LOCK prefix
...
- 시스템 레벨에서는 보호 모드를 위해 많은 레지스터들이 추가됨
CR0~CR4, DR0~DR3, DR6, DR7, IDTR, GDTR, LDTR
64-bit Assembly
- 레지스터 크기의 변화 및 추가
RAX(32b:EAX), RBX(32b:EBX), RCX(32b:ECX), RDX(32b:EDX),
RSI(32b:ESI), RDI(32b:EDI), RSP(32b:ESP), RBP(32b:EBP)
RIP(32b:EIP), RFLAGS(32b:EFLAGS)
기존 범용 레지스터 8개 외 범용 레지스터 8개 새로 추가 (R8~R15)
- 명령어의 추가/변형
REX prefix
Implicit Zero Extension
RIP relative addressing
...
- 내부 시스템 레지스터의 추가
위 내용들만 알아도 어셈의 95% 이상은 이해할 수 있다.
어셈블리어 공부 시 참고할 것.
BSF BSR 없는게 아쉬움.
정리 잘 했네. 개추 먹어라.
저기 써놓은 내용은 기초 중의 기초이고 전체 어셈의 95% 정도를 차지한다. 그리고 리버싱을 하게 되면 Calling Convention이라든지 Name Mangling이라든지... 이런 컴파일러적인 지식(호출 규약은 리버싱을 하지 않아도 알아야 한다만)과 PE 구조, 각종 커널 구조체, 커널 구조 등에 대해서도 빠삭해야 된다.
리눅스 리버싱이면 ELF 구조에 대해서도 알아야 겠지. 그리고 저게 어셈 공부의 끝이 아닌 이유는 코세 성님께서 말씀하신 대로 내가 상대적으로 비중이 적은 명령어들을 뺐고 프로세서가 발전함에 따라 확장 명령어들(예: MMX, SSE라던가)이 계속 생겨나서 실제로는 명령어가 엄청 많다. 저기 나온 건 가장 자주 쓰이는 기초적인 명령어들 및 개념들만 적어놓은 거임.
감사합니다. 복사해서 블로그에서 읽어야곘네여
와 정리 굿
이제 보니 하나 중요한 걸 빼먹었네. JMP에 보태서 JMP FAR까지도 알아둬야지 되겠군.
이제보니 16비트 어셈 명령어에서 "플래그 레지스터 관련" 카테고리에 STD/CLD를 빼 먹었다. 방향 플래그를 조작하는 문자열 관련해서 제일 중요한 명령어인데.
ㅋㅋㅋㅋㅋ 다시들어와보길잘했네 감사합니다.
그렇게 따지면 JP JR 도 자주 나옴 ㅋ
JP(Jump if Parity)는 Jcond(조건 분기)에 해당하는 부분이고, JR이라는 명령어는 처음 보는데 인텔 어셈인가요? 검색해도 안 나오네요.
아 맞다 JR 은 Z80 일듯.
codesaf.// z80이면 완전 고전인데...
내가 좀 어려성~
아주 먼 옛날 학부때 windows 시스템 파일들에서 자주 사용되는 명령어랑 명령어셋 디스어셈블해서 덤프 뜨는거 했었는데, 통계적으로 빈도 높은 애들부터 core level 에서 최적화 되면 성능을 올릴 수 있지 않을까 해서 말야. ㅋㄷㅋㄷ
코세 성님 학부 때면 윈도우 95도 안나왔을 거 같은데...
나 10대거든요?
나이가 들어서 난 요즘은 어셈은 안함
ref :
http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
이것만 보면 그냥 끝.
문제는 항상 언제나 공식 매뉴얼은 너무 상세해서 학습용으로는 부적절하다는 거지. Basis는 알고 매뉴얼을 보는 게 여러모로 좋다. 매뉴얼이 너무 방대해서 다 보기 힘듦 → 그때그때 모르는 것만 찾아서 보게 됨 → 다양하게 모름 → 뭔가 필요해지면 그게 뭔지 모름. 전체를 briefing해 주는 입문서라던가 개론 책이 필요한 이유지.
다시 말해 처음에는 수박 겉핥기 식으로 배운 뒤 심도있게 들어가는 게 이상적이라는 말임. 수박 겉핥기 식으로 배우기만 하고 끝내면 당연히 안되겠지만. 즉 내 말은 곧 숲을 보고 나무를 보라는 말이지.
ㅅㅅㅅ//던가->든가