Assembly
어셈블리어(assembly語, 문화어: 아쎔블러언어)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어이다.
컴퓨터 구조에 따라 사용하는 기계어가 달라지며, 따라서 기계어에 대응되어 만들어지는 어셈블리어도 각각 다르게 된다. 컴퓨터 CPU마다 지원하는 오퍼레이션의 타입과 개수는 제각각이며, 레지스터의 크기과 개수, 저장된 데이터 형의 표현도 각기 다르다. 모든 범용 컴퓨터는 기본적으로 동일한 기능을 수행하지만, 기능을 어떤 과정을 거쳐 수행할지는 다를 수 있으며, 이런 차이는 어셈블리어에 반영되게 된다.
게다가 단일 명령 집합에 대해 여러 니모닉과 통사론이 대응될 수 있다. 그런 경우에는 제조사가 만든 문서에서 쓰이는 것이 가장 자주 쓰이게 된다.
Memory model
- TINY
- SMALL
- COMPACT
Category
알아야할 기본사항
어셈블리 코드를 작성하는 프로그래머와 C 코드를 작성하는 프로그래머가 코드를 작성할때, 서로 시스템을 보는 관점이 다른데, 일반적으로 다음의 것들은 어셈블리 프로그래머가 되기 위해서는 반드시 숙지해야 하는 사항들이다.
- 8개의 레지스터중 program counter (%eip)는 다음 번에 실행될 명령어(next instruction)의 주소를 메모리에 보관하고 있는다.
- integer register file은 32비트 값을 저장하는 8개의 저장소(storage)를 가지고 있다. 이 저장소는 레지스터(register)라고 불리며, 주소와 정수값을 가질 수 있다. 몇몇의 레지스터는 프로그램의 실행을 관리할 목적으로 사용되며, 몇몇은 임시 저장소로 사용한다.
- 1비트 condition code 레지스터는 가장 최근에 실행된 연산 명령어에 대한 정보를 가지고 있다. 이것은 여러개의 condition code 의 조합에 의해서 프로그램의 흐름을 조절한다.
- floating-point register file은 실수(float)를 위한 8 개의 저장소를 가지고 있다.
- program memory 는 프로그램 실행을 위한 오브젝트 코드, 프로시저 호출(procedure call), 함수로부터의 return 값, 사용자에 의해 할당된 memory block 들을 가지고 있으며, 가상주소(virtual address) 를 사용한다.
- 한 개의 어셈블리 명령어는 아주 단순한 작업만을 한다. 예를 들면, 2 개의 수를 더하거나, 메모리에서 레지스터로 데이터를 전송하거나, 조건에 따라 분기하는 등의 임무를 수행한다.
- 일반적으로 C 언어에서는 여러가지 형태의 데이터 타입을 제공하고 있지만, 어셈블리에서는 데이타를 단지 바이트 단위의 연속적인 배열(array)로 본다. 예를 들면, C 언어에서의 배열과 struct는 연속적인 바이트 단위의 집합으로 표현되며, signed와 unsigned는 구분하지 않고, 포인터와 정수도 구분하지 않는다.
Syntax
-
MOV [목적지], [값]
- 목적지에 값을 입력한다.
-
MOV AX,56h
: AX 의 값이 56h이 된다. -
MOV AX,BX
: AX 의 값이 BX 의 값으로 대체 된다.
- asm:int
- 소프트웨어 인터럽트.
-
.global
.globl
- 8.41. .global symbol, .globl symbol
- ld에서 보여줄 심볼을 만든다.
- lea
- KLDP - assembly 에서 lea 명령어가 뭔가요..?
- Load Effective Address란 의미로 다음의 인자를 주소값으로 인식합니다.
- 혼동하면 안되는 것은 lea는 소스 레지스터가 가리키고 있는 곳의 값에 더하거나 빼는 것이 아니라 그 레지스터 값 자체에다 더하거나 뺀다는 점입니다.
-
pushw
,popw
- pushing and popping of 16-bit values.
-
pushl
,popl
- pushing and popping of 32-bit values.
-
pushq
,popq
- The new stack instructions pushq and popq allow pushing and popping of 64-bit values.
-
rep
- 뒤의 명령을 ECX가 0이 될때까지 반복한다.
-
jmp
,ja
,jb
,je
- 원하는 레이블로 점프한다. (ja: Jump if Above, jb: Jump if Below, je: Jump if Equal)
Sample
레지스터를 0으로 만드는 명령이다.
mov eax,0
등은 명령어의 크기가 커서 잘 사용되지 않는다.
Visual Studio 에서 Code Level 에서 Break point 설정방법
이럴때 break point를 원하는 코드에 __asm int 3;
이렇게 입력을 해놓으면, 실행시 이 시점에서 break point가 걸리게됩니다.
mov eax,0CCCCCCCCh
00401023 sub esp,40h ;지역변수를 위한 공간확보.
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-40h]
0040102C mov ecx,10h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
위소스는 함수 시작코드인 prelude 다음 부분에 지역변수를 할당하는 어셈소스이다. 밑에서 두번째 줄을 보면 0xcccccccch를 eax로 옮기는 작업을 한다. 스택에 변수가 생성되면 우선 이값으로 채워진다. 0xCC는 어셈코드 int 3로써 브레이크 인스트럭션이다.
cmp vs test
우선 두 명령어 Operand 두 개를 받아서 값을 비교하는데 사용되는 것 같습니다. 차이점을 비교해보면,
- CMP: 첫 번째 Operand에서 두 번째 Operand를 뺍니다. 이 연산의 결과는 ZF, Zero Flag에만 영향을 미칠 뿐 Operand에 영향을 미치지 않고 버려집니다.
- TEST: 첫 번째 Operand와 두 번째 Operand를 AND 시킵니다. 이 연산의 결과는 ZF에만 영향을 미치고 Operand에 영향을 미치지 않고 버려집니다.
결국 한 쪽은 빼기, 한 쪽은 AND인데 이 것으로 인해서
- CMP는 두 Operand가 완전히 같은지 판단할 수 있고
- TEST는 두 Operand가 모두 0인지 아닌지 판단할 수 있습니다.
TEST의 경우에는 두 Operand가 0이 아닌 경우를 제외하고는 값을 단정지을 수 없기 때문에(두 값이 0이 아닌 서로 다른 값일지라도 연산 결과는 0이 나올 수 있습니다.) TEST eax, eax와 같은 형태로 사용되어 대상의 값이 0인지 아닌지 확인할 때 사용됩니다.
See also
- CPU
- Netwide Assembler
- GNU Assembler
- Inline assembler
- Executable and Linkable Format (ELF)
- x86 calling conventions
- Disassembler
- Customasm - 사용자 정의 명령어 세트를 제공하여 소스 파일을 조립할 수 있는 어셈블러입니다.
Favorite site
- MASM32 web site
- Wikipedia (en) 어셈블리어에 대한 설명
- 인라인 어셈블리를 분석하자!!!!
- The GNU Assembler
- 리눅스 어셈블리 분석 기초
- Linux Assembly HOWTO
- Linuxdoc Sgml/Assembly-HOWTO: 어셈블리HOWTOV0.3C
- Linux Assembly HOWTO : 리눅스 어셈블리 하우투
- C를 어샘블러로 1
- SP Assembly Language Beginning 2
- Introduction to x86 Assembly Language – Part II
- x86 Assembly Guide
- [추천] 태초의 프로그래밍 언어 어셈블리: 메모리 주소 표현 방법들
- 요즘도 쓰는 언어 어셈블리
- 어셈블리어의 시작 (1) - 어셈블리어는 ?? (C코드를 어셈코드로 변환한 후 분석)
- PYRASIS.COM: 초보자를 위한 리버스 엔지니어링 상식 - 어셈블리 명령어
- PYRASIS.COM: 초보자를 위한 리버스 엔지니어링 상식 - 기계어를 어셈블리로 해석하기
- C언어에서 inline assembly 사용하기
- asm 간단한 함수 호출
Online tools
- [추천] Compiler Explorer - 각 코드와 어셈블리를 라인별로 구분 해주고 연동됩니다
- Quick C++ Benchmark - C++ 의 벤치마크를 온라인에서 즉석 비교
- C++ Insights - C++ 이 어떻게 컴파일 되는지 확인할 수 있다.
Tutorials
- [추천] 리눅스 어셈블리 제1~4강 3
Guide
- Win32 MASM 프로그래밍 소개(Visual C++이용) 16
- 레지스터와 어셈블리 그리고 스택 17
- Windows Assembly Programming Tutorial - Version 1.02 18
- ESP와 EBP
- <디스어셈블리 코드로 살펴보는> 2. 함수 호출규약(__cdecl, __stdcall)
- IA-32 assembly on Mac OS X
- mov와 lea 명령어 차이
- 어셈블리어 상태 레지스터(assembly status register) 19
Example
Reverse engineering
- 리버스 엔지니어링 스터디 2편. 스택 프레임(Stack Frame)
- 초보자를 위한 리버스 엔지니어링 상식 - 어셈블리 명령어
- [추천] Hack My Mind :: 어셈블리어 명령어 정리 24
Debugging
- x64 콜스택 인자 추적과 windbg의 Child-SP, RetAddr, Args to Child 값 확인
- Crash Dump Analysis Patterns (Part 14)
- WinDBG - 심볼 파일 맞추기
- Assembly - C 코드를 어셈블리로 분석해 보기
- Assembly - C언어의 if 문, switch 문을 어셈블리로 분석해 보기
- Assembly - CPU의 정보를 저장해둔 정보로 바꿔치기 하기(문맥 교환)
System call
Intel
References
-
Conversion_c_to_assembler.pdf ↩
-
Maybe-SP-Assembly_Language_Beginning.pdf ↩
-
Host: http://www.cs.utah.edu/ ↩
-
Linux_assembly_lecture_01.pdf ↩
-
Linux_assembly_lecture_02.pdf ↩
-
Linux_assembly_lecture_03.pdf ↩
-
Linux_assembly_lecture_04.pdf ↩
-
Based_assembly_language_for_beginners.pdf ↩
-
Korea.gnu.org-manual-as.zip ↩
-
Assembly_Programming_-_Optimization_Course_3.pdf ↩
-
P3ace_-_asm_01.pdf ↩
-
P3ace_-_asm_02.pdf ↩
-
P3ace_-_asm_03.pdf ↩
-
P3ace_-_asm_04.pdf ↩
-
P3ace_-_asm_05.pdf ↩
-
Win32_MASM_Programming_Intro_-_Visual_Cpp.pdf ↩
-
Register_and_assembly_and_stack_-_Asecurity.pdf ↩
-
Winasmtut.pdf ↩
-
Netstat.tistory.com_-_assembly_status_register.pdf ↩
-
Blog.daum.net_-sysnet924-assembly-_status_flag.pdf ↩
-
C_programmer_assembly.pdf ↩
-
Asm64-handout.pdf ↩
-
X64_cheatsheet.pdf ↩
-
Linkc.tistory.com_-_list_of_assembly_instructions.pdf ↩