어셈블리어 코딩 | 리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어] 19 개의 정답

당신은 주제를 찾고 있습니까 “어셈블리어 코딩 – 리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어]“? 다음 카테고리의 웹사이트 you.maxfit.vn 에서 귀하의 모든 질문에 답변해 드립니다: you.maxfit.vn/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 KnowlliPop 놀리팝 이(가) 작성한 기사에는 조회수 28,402회 및 좋아요 642개 개의 좋아요가 있습니다.

어셈블리어 코딩 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어] – 어셈블리어 코딩 주제에 대한 세부정보를 참조하세요

동영상과 텍스트로 공부하는 온라인 정보보안 교육 플랫폼 🎉 놀리팝 위드 🎉
더 많은 지식이 있는 새로운 세계에 초대합니다🤗
https://liveklass.com/ch/knowllipopwith
Pop Word : 어셈블리 언어
컴퓨터와 대화를 하려면 0과 1로 이루어진 기계어를 알아야합니다
보통 사람이라면 001011010001011010111 이런 숫자를 보고
이게 무슨 뜻인지 알기는 어렵지요
그래서 만들어진게 어셈블리 언어입니다
컴퓨터와 더 쉽게 대화하기 위해 만들어진 프로그래밍 언어이지요
프로그래밍 언어, 오늘날에는 C나 Python같이 어셈블리 언어보다 훨씬 쉽고 편리한 프로그래밍 언어들이 많이 있습니다
그럼에도 우리가 보안을 공부하려면 어셈블리 언어를 알아야하는 이유는 뭘까요?
리버싱과 시스템 해킹을 공부한다면 이 어셈블리로 이루어진 코드를 보고 분석을 해야하는 경우가 많기 때문입니다
오늘 동영상에서는 이 어셈블리언어의 기초에대해서 한번 알아보겠습니다
– 로우레벨프로그래밍언어와 하이레벨프로그래밍언어
– 인텔문법과 AT\u0026T문법의 차이점
– 레지스터의 종류와 역할
– 어셈블리 옵코드 종류와 역할
#어셈블리어 #어셈블리 #악성코드취약점분석

어셈블리어 코딩 주제에 대한 자세한 내용은 여기를 참조하세요.

어셈블리어 – 나무위키

예를 들어 C언어의 성능을 올리려고 인라인 어셈블리 코드를 삽입했다고 하자. 하지만 옛날 286 머신과 동일한 방식으로 어셈블리어 코딩을 해서 AH, …

+ 여기에 보기

Source: namu.wiki

Date Published: 9/23/2021

View: 82

[Assembly] 어셈블리어 기초 사용법 & 예제 총정리 – 코딩팩토리

어셈블리어란? 어셈블리어(assembly language)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어입니다. 전류가 흐른다 그렇지 않다로 …

+ 여기에 더 보기

Source: coding-factory.tistory.com

Date Published: 3/13/2022

View: 3855

Assembly(Assembly 기초/C소스 어셈블리로 코딩하기)

Assembly(Assembly 기초/C소스 어셈블리로 코딩하기). Kerberos_- 2017. 7. 25. 15:48. Assembly … ㆍ위와 같은 C언어문법 형태로 어셈블리에서는 불가능하다.

+ 여기에 자세히 보기

Source: mystyle1057.tistory.com

Date Published: 10/9/2022

View: 2436

어셈블리 프로그래밍 – HELLO_HELL?

어셈블리어(영어: Assembly language)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어이다. 컴퓨터 구조에 따라 사용하는 기계어가 …

+ 더 읽기

Source: crasy.tistory.com

Date Published: 3/10/2022

View: 786

어셈블리어 시작하기 – 리눅스 어셈블러 – x86-64 NASM

어셈블리어를 짜는 것은 CPU에다가 직접 0과1을 나열해서 코딩하는 것과 같습니다. 이렇다 보니 ‘누구나 코딩’ 이런 것은 좀 힘들지 않나 – 라고 볼 …

+ 여기에 표시

Source: smoothiecoding.kr

Date Published: 8/10/2022

View: 6133

어셈블리어 – 위키백과, 우리 모두의 백과사전

어셈블리어(영어: assembly language) 또는 어셈블러 언어(assembler language)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어이다.

+ 더 읽기

Source: ko.wikipedia.org

Date Published: 1/19/2022

View: 9728

C 언어 코드를 어셈블리 코드로 확인(변환) 하기 – 네이버 블로그

Debug 모드에서는 아주 간단하게 어셈블리 코드를 확인할 수 있습니다. 먼저 아래의 그림처럼 ‘디버그’ 메뉴의 ‘중단점 설정/해제(G)’ 메뉴를 사용 …

+ 더 읽기

Source: m.blog.naver.com

Date Published: 10/6/2021

View: 6007

어셈블리어(Assembly) 기초

그래서 이 기계 명령어를 좀더 이해하기 쉬운 기호 코드로 나타낸것(기계어와 1:1로 대응된 명령을 기술하는 언어)이 어셈블리어이다. 어셈블리 언어는 그 코드가 어떤 …

+ 여기에 보기

Source: aistories.tistory.com

Date Published: 11/14/2022

View: 2812

어셈블리어 입문하기_(어셈블리어란?) – I-Tstory

기계 코드 명령어로 변경됨. – 어셈블리어를 기계어 형태의 오브젝트 코드로 해석해주는 컴퓨터 언어번역 프로그램. – 어셈블리어 프로그램을 입력함.

+ 여기에 표시

Source: lucete1230-cyberpolice.tistory.com

Date Published: 7/30/2021

View: 3901

주제와 관련된 이미지 어셈블리어 코딩

주제와 관련된 더 많은 사진을 참조하십시오 리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어]. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어]
리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어]

주제에 대한 기사 평가 어셈블리어 코딩

  • Author: KnowlliPop 놀리팝
  • Views: 조회수 28,402회
  • Likes: 좋아요 642개
  • Date Published: 2020. 3. 23.
  • Video Url link: https://www.youtube.com/watch?v=yf7yFJHTif8

[Assembly] 어셈블리어 기초 사용법 & 예제 총정리

어셈블리어란?

어셈블리어(assembly language)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어입니다. 전류가 흐른다 그렇지 않다로 구성되는 0과 1의 이진수로 프로그램을 하는 기계어는 인간의 관점에서는 컴퓨터가 바로 읽을 수 있다는 점만 빼면 장점이 없는 언어이기 때문에 이를 보완하기 위해 나온 언어가 어셈블리어입니다. 기계어와 명령어가 1:1로 대응되는 단어들로 구성되어 있습니다. 고급언어는 컴파일하는 시간이 오래 걸리는 단점이 있는 반면 저급 언어는 컴퓨터와 가까운 언어이기 때문에 컴파일을 해도 간단한 명령으로 실행돼서 실행 속도가 굉장히 빠릅니다. 하지만 저급 언어는 배우기가 어렵고 유지보수가 힘들다는 이유로 특수한 경우를 제외하고는 사용되지 않고 있습니다. 하지만 임베디드 시스템이나 커널 프로그래밍, 컴퓨터 보안 등은 어셈블리어를 알아야 하고 디버깅이 불가능한 라이브 서비스를 진행하고 있는 환경에서 어느정도 디버깅을 할 수 있게 해주며 특히 어셈블리에 대한 전반적인 지식을 배움으로써 컴퓨터의 구조를 더 자세히 알 수 있어 어셈블리어로 코딩을 할 정도는 아니어도 구글링을 하며 해석 정도는 할 수 있어야 한다고 생각합니다.

Intel 문법과 AT&T 문법

어셈블리어에는 Intel문법과 AT&T 문법이 존재하며 또한 이들은 서로 호환되지 않습니다. 서로의 문법에 대해 차이점이 존재합니다.

명령어 수행 방식

만약 위와 같은 명령어가 있다고 가정할 때 Intel Operand의 경우 Operand2가 Source고 Operand1이 Destination이 되며 EBX의 값을 EAX에 더한다라는 뜻이 되고 AT&T의 경우에는 반대가 되어 EAX의 값을 EBX로 더한다라는 뜻이 됩니다.

Opcode : 명령어

Operand : 피 연산자

숫자 표기 방식

Intel (숫자를 그대로 사용)

ex) 1, 2, 3, 4, 5

AT&T (앞에 $를 붙여서 사용)

ex) $1, $2, $3, $4, $5

레지스터 표기 방식

Intel (명칭 그대로 사용)

ex) EAX, EBX, EBP

AT&T (앞에 %를 붙임)

ex) %EAX, %EBX, %EBP

이렇듯 두 가지 문법이 서로 차이점이 있습니다. 이 두 가지 문법 중 저희와 같은 개발자들이 많이 사용하는 것은 단연 Intel문법입니다. 이 포스팅 또한 Intel문법의 사용법을 기준으로 작성되었습니다.

어셈블리에서 사용되는 레지스터 종류

레지스터란?

레지스터란 CPU의 요청을 처리하는 데이터의 임시공간입니다. 레지스터는 공간이 작고 가격은 비싸지만 CPU에 직접 연결되어 있어서 연산 속도가 매우 빠릅니다. (RAM 보다도 훨씬 더) CPU는 자체적으로 데이터를 저장할 수 없으므로 레지스터를 이용하여 연산처리와 번지지정을 도와줍니다. 32비트의 경우에는 레지스터의 처음이 E로 시작하고 64비트는 R로 시작합니다.

범용 레지스터

EAX : 사칙연산 등 산술 연산에 자동으로 사용되며, 함수의 반환 값을 처리할 때도 사용됩니다.

EBX : 간접 번지 지정에 사용됩니다. 산수, 변수를 저장합니다.

ECX : 반복(Loop)에서 반복 Count 역할을 수행합니다.

EDX : EAX를 보조하는 역할을 합니다. 예를 들어 나누기를 진행할 경우 몫은 EAX에 나머지는 EDX에 저장됩니다.

인덱스 레지스터

ESI : 복사나 비교를 할 경우 출발지 주소를 저장하는 레지스터입니다.

EDI : 복사나 비교를 할 경우 목적지 주소를 저장하는 레지스터입니다.

포인터 레지스터

EIP : 다음에 실행할 명령어의 주소를 가지고 있는 레지스터입니다. 현재 실행하고 있는 명령어가 종료되면 이 레지스터에 있는 명령어를 실행하게 됩니다.

ESP : Stack Pointer의 가장 최근에 저장된 공간의 주소를 저장하는 레지스터입니다.

EBP : Stack Pointer의 기준점(바닥 부분)을 저장하는 레지스터입니다.

어셈블리어 자주 사용하는 명령어

명령어 예제 설명 분류 push push eax eax의 값을 스택에 저장 스택 조작 pop pop eax 스택 가장 상위에 있는 값을 꺼내서 eax에 저장 스택 조작 mov mov eax, ebx 메모리나 레지스터의 값을 옮길때 사용 데이터 이동 inc lnc eax eax의 값을 1증가시킨다 (++) 데이터 조작 dec dec eax eax의 값을 1감소시킨다 (–) 데이터 조작 add add eax, ebx 레지스터나 메모리의 값을 덧셈할때 쓰인다. 논리, 연산 sub sub eax, ebx 레지스터나 메모리의 값을 뺄셈할때 쓰인다. 논리, 연산 call call proc 프로시저를 호출한다. 프로시저 ret ret 호출했던 바로 다음 지점으로 이동 프로시저 cmp cmp eax, ebx 레지스터와 레지스터의 값을 비교 비교 jmp jmp proc 특정한 곳으로 분기 분기 int int $0x80 OS에 할당된 인터럽트 영역을 system call 인터럽트 nop nop 아무 동작도 하지 않는다. (No Operation)

주로 사용되는 건 위의 명령어들이며 이 정도만 알아두어도 어셈블리어를 해석하는데 큰 문제가 없습니다. 만약 좀 더 다양한 명령어를 보고 싶다면 아래 글을 참고해주시기 바랍니다.

[Assembly] 어셈블리어 명령어 총정리

어셈블리어 예제

#include int main() { int a = 1; int b = 2; int c = a + b; printf(“%d”, c); }

예를 들어 위의 코드를 어셈블리어로 바꾸면 어떻게 될까요?

push ebp mov ebp,esp sub esp,0E4h push ebx push esi push edi lea edi,[ebp+FFFFFF1Ch] mov ecx,39h mov eax,0CCCCCCCCh rep stos dword ptr es:[edi] mov ecx,9AC003h call 009A1316 mov dword ptr [ebp-8],1 mov dword ptr [ebp-14h],2 mov eax,dword ptr [ebp-8] add eax,dword ptr [ebp-14h] mov dword ptr [ebp-20h],eax mov eax,dword ptr [ebp-20h] push eax push 9A7D08h call 009A10CD add esp,8 xor eax,eax pop edi pop esi pop ebx add esp,0E4h cmp ebp,esp call 009A123F mov esp,ebp pop ebp ret

어셈블리어로 코드를 변환하면 이렇게 됩니다. 그럼 차근차근 해석해볼까요? 우선 특정 함수에 접근하려면 사용할 스택의 공간을 만들어야 합니다. ebp를 push한뒤 esp의 값을 ebp에 넣어주어 기존에 사용하던 esp의 값(스택의 꼭대기)을 스택의 가장 밑 부분으로 만들었습니다. 그런 뒤 esp(스택의 꼭대기)에 0E4h(16진수)의 크기를 할당하여 ebp ~ esp까지 공간을 할당하여 사용할 스택의 크기를 만들었습니다.

그런 뒤 dword ptr [ebp-8]에 1이라는 값을 넣고 dword ptr[ebp-14h]에 2라는 값을 넣었습니다. 이것이 위의 코드에서 a의 변수에 1을 넣고 b라는 변수에 2를 넣은 것입니다. 이렇듯 어셈블리어에서는 변수의 이름 같은 것이 없습니다. 단지 메모리 주소만 있을 뿐입니다.

그런 다음 eax에 다시 [ebp-8]에 있는 값을 넣고 eax와 [ebp-14]의 값을 더했습니다. 이 부분이 바로 a+b입니다. 그런 뒤 mov 함수를 통해 [ebp-20h] 이 부분이 변수 c가 되겠습니다. 여기에 방금 add한 값을 넣어줍니다. 그런 뒤 call 009A10CD을 통해 print함수를 출력합니다. 그리고 마지막으로 사용이 끝난 레지스터들을 pop해줍니다.

간단한 C언어 코드인데도 어셈블리어로 번역하면 이렇게 됩니다. 명령어 위주로 되어있어 명령어만 안다면 해석이 어렵지는 않으나 전체적으로 해석해야 할 문장이 너무나도 길죠. 간단한 문장이니 이 정도로 끝났지 긴 프로그래밍이면 전체 번역은 불가능하다고 봐야 합니다. 그래서 결국 부분 부분 끊어서 봐야 합니다. 요즘에는 어셈블리어에 가독성이 좋게끔 고급 프로그래밍 언어를 위에 추가해준다거나 변수 이름을 보이게 하여서 가독성이 좋게 해주는 방법이 많이 나오고 있습니다. 이를 활용하는 것도 좋은 방법이 될 수 있겠습니다.

Assembly(Assembly 기초

Assembly

Assembly 기초

mov al, ‘A’ mov reg32 imm8

ㆍ’A’ 아스키코드는 imm8 로 나타낸다.

mov eax , number1 mov reg32, memory

ㆍcpu 밖으로 bus를 타고 나감으로 속도가 느리다.

mov eax, ebx mov reg32, reg32

ㆍ레지스터 간의 이동 이므로 속도가 빠르다.

mov [eax], 10 :: [eax] = *eax 동일한 형식

ㆍ포인터를 사용한 것은 indirect 라고 한다. (간접 참조)

number2 = 10; number1 = number2;

ㆍ위와 같은 C언어문법 형태로 어셈블리에서는 불가능하다.

(Cpu 를 거치지않고 메모리에서의 이동은 두뇌가 없는 것과 같다.)

ㆍ기계어 보는 법은 다음과 같다.

mov number1, eax mov direct, EAX

ㆍ위 메모리뷰 에서 a3는 mov의 기계어 Opcode 이다.

C소스 Assembly로 코딩하기

EX) 어셈블리로 바꾸어 코딩할 C소스

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include < stdio.h > int main() { int sum = 0 ; int temp = 0 ; printf ( “Enter the x: ” ); scanf ( “%d” , & sum); printf ( “Enter the y: ” ); scanf ( “%d” , & temp); sum = temp + sum; printf ( “Enter the z: ” ); scanf ( “%d” , & temp); temp = temp * 2 ; sum = sum – temp; + + sum; – sum; printf ( “(x + y – 2z + 1) is %d

” , sum); return 0 ; } Colored by Color Scripter cs

위 C소스를 어셈블리로 코딩하면 다음과 같다

EX) first.asm

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 . 386 .MODEL FLAT ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD INCLUDE io.h cr EQU 0Dh Lf EQU 0Ah .STACK 4096 .DATA number1 DWORD ? number2 DWORD ? prompt1 BYTE “Enter First Number : ” , 0 prompt2 BYTE “Enter Second Number : ” , 0 prompt3 BYTE “Enter Third Number : ” , 0 string BYTE 40 DUP (?) label1 BYTE cr, Lf, “(x + y – 2z + 1) is” sum BYTE 11 DUP (?) BYTE cr, Lf, 0 .CODE _start: output prompt1 ; printf ( “Enter First Number : ” ); input string, 40 ; scanf ( “%d” , & sum); atod string mov number1, eax output prompt2 ; printf ( “Enter Second Number : ” ); input string, 40 ; scanf ( “%d” , & temp); atod string mov number2, eax mov eax, number1 add eax, number2 mov number1, eax ; sum = temp + sum; output prompt3 ; printf ( “Enter Third Number : ” ); input string, 40 ; scanf ( “%d” , & temp); atod string mov number2, eax mov eax, number2 add eax, eax mov number2, eax ; temp = temp * 2 ; mov eax, number1 sub eax, number2 mov number1, eax ; sum = sum – temp; mov eax, number1 inc eax mov number1, eax ; + + sum; mov eax, number1 neg eax ; – sum; mov eax, number1 dtoa sum, eax output label1 INVOKE ExitProcess, 0 PUBLIC _start END Colored by Color Scripter cs

실행 결과

어셈블리 프로그래밍

HELLO? (157) 스터디 (6) Windows 구조와 원리 OS를 관.. (6) Development (44) Android (5) Assembly (4) C/C++ (11) C# (0) HTML (1) JAVA (2) JSP (3) JS Script (2) Linux Shell Script (2) Open GL (1) PHP (0) Python (1) QT library (3) SQL (1) Swift (1) MongoDB (0) Express JS (1) Angular JS (1) Node JS (1) SpongePoweredForgePluginDev.. (2) Unity3d (1) Docker (0) Linux (22) Linux Kernel Study (1) Network (9) WireShark (1) Network Theory (6) Hack the packet 2013 (2) Reversing (50) Windows PE (10) Windows Reversing (1) Linux PE (0) Linux Reversing (0) Android Reversing (2) Reversing Tools (8) CodeEngn (25) Reversing.kr (2) abex’s (2) Sites (3) System (12) FTZ (9) Buffer Over Flow (3) GDGkr (1)

x86-64 NASM

어셈블리어 시작하기

어셈블리어는 기계어에 1대1로 대응하는 저수준(low level langugae) 언어입니다. 오늘날 대부분의 응용 프로그램은 자바(Java)나 파이썬(Python)같은 고수준(high level language) 언어로 개발해서 어셈블리어의 존재를 잘 모르는 사람도 있을 겁니다. 하지만 여전히 시스템 프로그래밍과 임베디드, IT보안 등 하드웨어 레벨을 다루는 분야에서 사용하고 있고, 근본 언어기 때문에 미래에도 쉽게 없어지지는 않을 겁니다.

대학의 컴퓨터공학부에서는 많지는 않지만 시스템 소프트웨어라는 과목의 수업에서 어셈블리어 기초를 아직도 가르치고 있습니다. 다만 어셈블리어는 아키텍쳐에 의존하기 때문에 write once run everywhere 가 먹히지 않습니다. 대학의 한 학기 강의로는 특정 어셈블리어 하나 정도를 커버할 수 있겠네요. 요즘은 쓸만한 언어들의 크로스 플랫폼에 익숙하다면 어셈블리어를 배운다는 것은 약간 더 시간 투자적으로 고려할 필요도 있습니다. (CPU 종류에 따라 달라지므로)

그렇다고 어셈블리어를 너무 가성비로 보는 것은 좋지 않다는 사람들도 있는데요. 고수준 언어를 더 잘 하기 위해서라도 밑바닥에서 머신 레벨의 방식을 학습해야 한다는 주장도 있습니다. 이러한 논쟁은 자바가 등장하고 모든 대세가 OOP로 쏠려있던 20여년 전부터 지금까지 이어져 오고 있습니다.

약간 구닥다리 느낌적으로 20년 전 어느날 C++과 자바의 초기 시대에 한 프로그래머가 ‘라떼는 말이야~ 어셈블리어로 밤새도록 쏼라쏼라~’ 라며 영웅담을 늘어놓고 있지 않았을까 생각이 듭니다. 지금은 IT사업으로 성공해 있을지도 모르겠네요. (가상의 캐릭터를 상상해 본 겁니다)

일단 어셈블리어는 컴퓨터 아키텍쳐 자체를 모르면 조금 시간이 더 걸리는 언어입니다. 고수준 언어들은 그 안의 로직이 그래도 인간적인데(OOP) 여기서는 레지스터 몇개와 메모리 주소, 스택 같은 지극히 추상적인 개념을 도구로 코드를 작성합니다. 컴퓨터는 흔히 0과1로 동작한다고 말합니다. 어셈블리어를 짜는 것은 CPU에다가 직접 0과1을 나열해서 코딩하는 것과 같습니다. 이렇다 보니 ‘누구나 코딩’ 이런 것은 좀 힘들지 않나 – 라고 볼 수 있습니다.

요즘은 심지어 초등학교 아이들에게도 코딩을 가르치는데 코딩에도 난이도가 있습니다. 누구나 할 수 있는 코딩(노인과 아이도 가능), 좀 배우면 누구나 할 수 있는 코딩(HTML/CSS – HTML is not a programming language?), 전문 교육기관에서 배우는 코딩(JavaScript, Java) 등 세분화가 되는데 이 모든 것을 ‘코딩’이라는 도매급으로 잡기엔 맞지 않는 부분이 있습니다.

어셈블리어는 컴퓨터를 직접 조작해야 하므로 언어로써 가장 어렵고 지루하긴 하지만 근본적인 원리를 이해할 수 있다는 점에서 고수준 언어의 사용자들에게도 도움이 됩니다. 또 운영체제와 커널의 원리에 대해서도 알 수 있습니다. 리눅스 유저는 얻을 수 있는게 많지 않을까 싶습니다.

어셈블리어를 배우는 이유?

이유가 여러가지가 있습니다. 어셈블리어로 GUI를 구현할 것은 아니겠지요.(가능은 하다)

필요에 의해서(시스템/보안 엔지니어 등)

고수준 언어를 더 잘 이해하기 위해서

(C언어와 함께 배우면 시너지가 난다)

(C언어와 함께 배우면 시너지가 난다) 하드웨어 레벨을 이해하기 위해서

도전의식으로 (고난이도에 도전)

순수한 컴퓨팅의 재미로(Nerd?)

NASM (Netwide Assembler)

넷와이드 어셈블러는 인텔 x86 아키텍쳐의 어셈블러 입니다. 64비트 윈도우 환경에서도 사용할 수 있지만 NASM은 리눅스가 자연스럽습니다. 윈도우에는 Visual Studio에서 C++에 사용할 수 있는 어셈블리어인 MASM이 있습니다. 어셈블리어는 CPU 아키텍쳐에 따라 명령어가 달라지는데 또 운영체제에 따라서 달라집니다. 그러니까 처음에 어떤 CPU와 운영체제에서 돌아가는 어셈블러를 사용할지 파악해야 합니다. 여기서는 x86-64 인텔 CPU와 우분투 리눅스(WSL2)에 NASM 어셈블러를 설치하겠습니다.

apt-get으로 nasm 을 설치합니다.

sudo apt-get install nasm

버전체크으로 설치가 되었는지 체크합니다.

nasm –version

Hello World

프로그래밍 전통에 따라 Hello World 를 콘솔에 출력해보겠습니다. 처음에 보면 이 몇 줄을 이해하는데만 하루 종일도 걸릴 수 있습니다. 문법적인 내용을 몰라서 그런 거니까 당황할 필요는 없습니다. C나 자바같이 고수준 언어와는 많이 달라 보입니다. 문법은 시간이 지나면 익숙해질 겁니다.

section .data msg: db “Hello World!”,10 len: equ $-msg section .text global _start _start: mov rax, 1 ;system call id 1 mov rdi, 1 ;FD stdout mov rsi, msg ;bytes(ADDR) to write mov rdx, len ;byte length syscall _last: mov rax, 60 mov rdi, 0 syscall

먼저 nasm 으로 오브젝트 코드(기계어)로 바꾼 후 ld 로 링크합니다. ./main으로 실행한 결과는 화면에 Hello World!를 출력합니다.

nasm -f elf64 -g main.asm -o main.o ld -o main main.o

Hello World 가 출력되었다면 이제 어셈블리어를 시작할 수 있습니다. 아쉽지만 여기서 모든 것을 상세히 설명하지는 않겠습니다. 크게 구조를 보면 어셈블리어는 세개의 영역이 있습니다. section .data / section .bss / section .text 입니다. 각각 용도가 다른데 여기서 쓰인 .data는 정적 변수 msg 와 상수인 len을 선언합니다. .text는 프로그램 코드입니다. 위에서 부터 순차적으로 실행합니다. _start: 이것을 레이블이라 하는데 다음 _last: 가 나오기 전까지의 내용이 시스템콜 입니다. rax 의 1번은 stdout 에 쓰는 것 입니다. (mov rax, 1 – 1을 rax 레지스터에 전송) _last: 레이블 내용은 프로그램을 종료합니다.

코드만 봐서는 무슨 내용인지 이해가 잘 안됩니다. 내용적으로만 정리하면 이 코드는 Hello World 라는 문자열을 시스템 콜을 사용해서 표준 출력인 스크린에 출력하고 정상 종료합니다. 이제 하나씩 명령어 문법을 배우면 어느새 머리속에서 CPU 동작을 따라하게 될지도 모릅니다.

요약

먼저 어셈블리어 시작의 개요를 알아봤습니다. 다음은 리눅스 환경에 Nasm 어셈블러를 설치하고 Hello World를 출력했습니다. 간단한 코드의 실행이지만 x86 CPU에 직접 명령어(instruction)를 실행 할 수 있게 되었습니다. 이제부터 하나씩 알아가 보도록 하겠습니다.

참고링크

NASM Documentation

NASM-2.15.05 (linuxfromscratch.org)

NASM Tutorial (lmu.edu)

위키백과, 우리 모두의 백과사전

어셈블리어 모토로라 MC6800 어셈블리어. 패러다임 명령형, 비구조적 발표일 1949년

어셈블리어(영어: assembly language) 또는 어셈블러 언어(assembler language)[1]는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어이다.

컴퓨터 구조에 따라 사용하는 기계어가 달라지며, 따라서 기계어에 대응되어 만들어지는 어셈블리어도 각각 다르게 된다. 컴퓨터 CPU마다 지원하는 오퍼레이션의 타입과 개수는 제각각이며, 레지스터의 크기와 개수, 저장된 데이터 형의 표현도 각기 다르다. 모든 범용 컴퓨터는 기본적으로 동일한 기능을 수행하지만, 기능을 어떤 과정을 거쳐 수행할지는 다를 수 있으며, 이런 차이는 어셈블리어에 반영되게 된다.

게다가 단일 명령 집합에 대해 여러 니모닉과 통사론이 대응될 수 있다. 그런 경우에는 제조사가 만든 문서에서 쓰이는 것이 가장 자주 쓰이게 된다.

개념 [ 편집 ]

어셈블러 [ 편집 ]

어셈블러(assembler)는 어셈블리어를 기계어 형태의 오브젝트 코드로 해석해 주는 컴퓨터 언어 번역 프로그램을 말한다. 어셈블러는 기본 컴퓨터 명령어들을, 컴퓨터 프로세서가 기본 연산을 수행하는데 사용할 수 있는 비트 패턴으로 변환시키는 프로그램이다. 몇몇 사람들은 이러한 명령어들을 어셈블러 언어라고 부르며, 어셈블리 언어라고 부르는 사람들도 있다. 니모닉 기호(mnemonics)를 opcode로 변환하고 메모리 위치와 기타 존재물에 따라 식별자를 다시 분석함으로써 목적 코드를 만들어낸다.[2] 거꾸로 기계어를 어셈블리어로 바꾸는 것은 “역(逆)어셈블러”(disassembler)이다. 고급 언어와는 달리 어셈블리어는 간단한 문장에 대해 기계어와 일대일 대응 관계가 있지만, 자주 쓰이는 몇 명령은 둘 이상의 기계어 명령을 묶어 하나의 어셈블리 명령어에 대응시키기도 한다.

이것은 어셈블리 명령 부호를 오피코드로 해석할 뿐만 아니라 메모리의 위치들을 이름으로 표시하는 기능, 매크로를 통한 문장 치환 기능 등을 함께 제공한다. 높은 수준의 어셈블러는 고급 제어 구조, 높은 수준의 프로시져/함수 선언 및 호출, 높은 수준의 자료형 추상화 같은 높은 수준의 언어 추상화 기능을 제공하기도 한다.

MIPS, Sun Sparc, HP PA-RISC과 같은 RISC 기반 아키텍처를 위한 현대의 어셈블러는 함수 스케줄링 기능을 가지고 있어서 중앙처리장치의 파이프라인을 효과적으로 사용할 수 있다. 이 어셈블러는 1950년대부터 계속 쓰여 왔으며, 고급 언어를 위한 컴파일러에 견주어 보면 구조가 매우 간단하다. 크로스 어셈블러는 다른 프로세서를 위한 코드를 만든다. 어셈블러가 실행되는 단계를 어셈블리 타임이라고 한다.

패스의 수 [ 편집 ]

어셈블러에는 두 가지 종류가 있는데, 실행 프로그램을 만들기 위해 얼마나 많은 패스가 소스를 거치는지에 따라 다르다.

1패스(one-pass) 어셈블러는 소스 코드를 한 번만 거친다.

다중 패스(multi-pass) 어셈블러는 처음 패스들에서 모든 기호와 관련 값들이 포함된 테이블 하나를 만들고 나중 패스들에서 테이블을 이용하여 코드를 만들어낸다.

1패스 어셈블러들을 이용하는 본래 이유는 어셈블리의 속도 때문이다. 2차 패스가 되돌아가기를 요구할 수도 있기 때문이다. 그러나 현대의 컴퓨터는 납득하기 어려운 지연 없이 다중 패스 어셈블리를 수행한다. 다중 패스 어셈블러는 링크 프로세스를 더 빠르게 한다는 장점이 있다.[3]

고급 어셈블러 [ 편집 ]

더 복잡한 고급 어셈블러는 다음과 같은 언어 추상물을 제공한다:

진보화된 제어 구조

높은 수준의 프로시저/함수 선언 및 호출

구조/레코드, 유니언(union), 클래스, 집합을 포함한 높은 수준의 추상 자료형

복잡한 매크로 처리

클래스, 오브젝트, 추상화, 다형성, 상속과 같은 객체 지향 프로그래밍 기능[4]

어셈블리어 [ 편집 ]

기계어는 실제로 컴퓨터의 CPU가 읽어서 실행할 수 있는 0과 1로 이루어진 명령어의 조합이다. 이러한 각 명령어에 대해 사람이 알아보기 쉬운 니모닉 기호(mnemonic symbol)를 정해 사람이 좀 더 쉽게 컴퓨터의 행동을 제어할 수 있도록 한 것이 어셈블리 언어이다.

예를 들어,

10110000 01100001

는 x86 계열 CPU의 기계어 명령이고, 이것을 어셈블리어로 옮겨쓰면 다음과 같다.

mov al , 061 h

명령어 mov는 영어 move를 변형한 니모닉이며, al은 CPU안에 있는 변수를 저장하는 레지스터의 하나이다. 그리고, 061h는 16진수 61 (즉 십진수 97, 이진수 01100001)이다. 이 한 줄의 뜻은 16진수 61을 al레지스터에 넣으라는 뜻이며, 1과 0의 반복인 기계어보다 사람이 혼동없이 이해하기 한결 쉽다. 어셈블리어는 이러한 문장들로 구성된다.

헬로 월드 프로그램 [ 편집 ]

다음은 NASM x86 어셈블리어로 구현한 헬로 월드 프로그램이다.

adosseg .model small .stack 100 h .data hello_message db ‘ Hello , World ! ‘ , 0 dh , 0 ah , ‘ $ ‘ .code main proc mov ax , @ data mov ds , ax mov ah , 9 mov dx , offset hello_message int 21 h mov ax , 4 C00h int 21 h main endp end main

같이 보기 [ 편집 ]

각주 [ 편집 ]

C 언어 코드를 어셈블리 코드로 확인(변환) 하기

4. Debug 모드와 Release 모드에서 생성하는 어셈블리 코드는 다르다!

2번과 3번에서 보여드린 어셈블리 코드를 비교해보면 알겠지만 같은 C 언어 소스 코드라도 Debug 모드로 컴파일 했을 때와 Release 모드로 컴파일 했을 때의 어셈블리 코드가 다릅니다. 왜냐하면 Release 모드에서는 디버깅을 위한 정보가 추가되지 않고 코드 최적화 기술도 적용되기 때문에 C 언어 코드를 그대로 번역하지 않아서 그렇습니다. 즉, 컴파일러가 판단해서 의미 없는 코드는 제거하고 비효율적인 코드는 효율적으로 바꾸는 작업이 이루어지기 때문입니다.

이와 관련된 좀 더 자세한 내용은 아래에 링크한 글을 참고하기 바랍니다.

aistories :: 어셈블리어(Assembly) 기초

어셈블리어(Assembly) 입문자를 위한 어셈블리어 기초

## 목차 ##

0x01. 어셈블리 언어란? & 배우는 목적

0x02. 어셈블리 언어를 위한 기본 지식

0x03. 어셈블리 명령어의 구성

0x04. 주소지정방식의 이해

0x05. 어셈블리 명령어 정리

0x06. 어셈블리 명령어 상세

0x07. 참조 사이트 및 문서

0x01. 어셈블리 언어란? & 배우는 목적

CPU 에는 해당 프로세서에 명령을 내리기 위해 고유의 명령어 세트가 마련되어 있는데 이 명령어 세트를 기계어라고 한다. 이 기계어는 숫자들의 규칙조합임으로 프로그래밍에 상당히 난해하다. 그래서 이 기계 명령어를 좀더 이해하기 쉬운 기호 코드로 나타낸것(기계어와 1:1로 대응된 명령을 기술하는 언어)이 어셈블리어이다. 어셈블리 언어는 그 코드가 어떤 일을 할지를 추상적이 아닌, 직접적으로 보여준다. 논리상의 오류나, 수행 속도, 수행 과정에 대해 명확히 해준다는 점에서 직관적인 언어이다. 어셈블리 언어를 사용하면 메모리에대한 이해도도 높아진다. 어셈블리를 익히고, 배우는데 있어서는 여러 가지 목적이 있을 수있다. 컴퓨터 시스템&구조를 좀 더 깊게 이해하고, 메모리상의 데이터나 I/O기기를 직접 액세스 하는등의 고급언어에서는 할 수 없는 조작을위해서이다. 프로그램의 최적화 및 리버스 엔지니어링을 위해서도 필요하다.

+ 2줄 요약 +

– 어셈블리 언어는 기계어와 1:1 대응을 하는 언어이다.

– 어셈블리 언어를 배우면 시스템을 이해하는데 도움이 된다.

0x02. 어셈블리를 위한 기본 지식

(1) 기본적인 하드웨어

1) CPU

– 메모리에 있는 내용을 읽고, 쓰고 데이터를 메모리와 각 레지스터로 보낸다.프로그램의 명령을 해석하고 실행한다.하나의 프로세서는 12~14개의 레지스터를 가지고 있으며,CPU의 연산, 논리 장치는 숫자와 기호에 관한 연산자를 인식한다. 보통 이러한 장치들은 기본적인 연산만을 수행할 수 있다(덧셈, 뺄셈, 곱셈, 나눗셈, 숫 자비교). 퍼스널 컴퓨터는 한번에 처리할 수있는 비트수(Word) 따라서 분류된다.

2) RAM

– 반도체로 조립된 셀들의 집합. 프로세스가 프로그램을 실행시키고 작동하기위해서 필요한

정보들을 저장하는데 쓰인다. 각각의 셀들은 숫자값을 포함하고 주소가 정해질 수 있는 형

식이며 프로그램에서 흔히 메모리라고 하는 것들은 메인메모리, 즉, 램이라고 할 수 있다.

(2) 80×86 프로세서

1) CPU 레지스터 종류 : 범용 레지스터, 상태 레지스터, 플래그 레지스터

– 레지스터 : CPU내부의 기억장소로 PC가 정보를 처리하기 위해서는 정보가 특정한 셀에 저장되어 있어야 한다. 이러한 셀을 레지스터라고 불린다. 레지스터들은 8또는 16비트 플립-플롭 회로들의 집합이다. 플립-플롭 회로란 두 단계의 전압으로 정보를 저장할 수 있는 장치이다. 낮은 전압은 0.5 볼트이고 높은 전압은 5볼트이다. 낮은단계의 에너지는 0으로 해석되고 높은 전압은 1이다. 이 상태는 보통 비트로 불리며 컴퓨터의 가장 작은 정보 단위이다.

< 레지스터의 구조 >

① 데이터 레지스터

– 데이터 레지스터는 각종 데이터 처리를 대상으로 하는 하는 32비트 레지스터 및 16비트 레지스터 일부를 프로그래머가 명령 중에서 자유롭게 지정을 할 수 있는 범용 레지스터이다.

: EAX, EBX, ECX ,EDX

② 포인터 레지스터

: ESP, EBP

③ 인덱스 레지스터 (Index register)

: ESI, EDI

④ 세그먼트 레지스터 (segment register)

: CS, DS, SS, ES

+ 범용 레지스터 +

32Bit 16Bit 상위8Bit 하위8Bit 기능 EAX AX AH AL 누산기(Accumulator, 중간 결과를 저장해 놓음)

레지스터라 불리며, 곱셈이나 나눗셈 연산에 중요하게 사용 EBX BX BH BL 베이스 레지스터라 불리며 메모리 주소 지정시에 사용 ECX CX CH CL 계수기(Counter)레지스터라 불리며 Loop등의 반복 명력에 사용 EDX DX DH DL 데이터(Data)레지스터라 不利며 곱셈, 나눗셈에서EAX함께

쓰이며 부호 확장 명령 등에 사용 ESI SI 다량의 메모리를 옮기거나 비교할 때 그 소스(Source)의 주소를

가진다 EDI DI 다량의 메모리를 옮기거나 비교할때 그 목적지의 주소를 가리키다. ESP SP 스택 포인터로 스택의 최종점을 저장한다.

EBP BP ESP를 대신해 스택에 저장된 함수의 파라미터 지역 변수의

주소를 가리키는 용도로 사용된다.

+ 세그먼트 레지스터 +

16Bit 기능 ES 보조 세그먼트 레지스터다. 두 곳 이상의 데이터 저장영역을 가리켜야 할 때 DS와 함께 사용된다.

하지만 32Bit 프로그램에서는 DS와 ES가 같은 영역을 가리키고 있기 때문에 굳이 신경 쓰지 않아도 된다. CS 코드 세그먼트를 가리키는 레지스터. 프로그래머 코드의 시작조소를 가지고 있다. SS 스택 세그먼트를 가리키는 레지스터. 스택의 시작 주소를 담고 있다.

스택 조작에 의해서 데이터를 처리하는 동작이 이루어 진다. DS 데이터 세그먼트를 가리키는 레지스터.

프로그래머가 정해놓은 데이터의 시작주소를 담고 있다. FS 보조 세그먼트 레지스터. FS, GS는 286 이후에 추가된 것으로 운영체제를 작성하는 게 아니라면 없듯이 여겨도 된다. GS

+ 상태 레지스터+

32Bit 16Bit 기능 EIP IP EIP는 현재 실행되고 있는 프로그램으 ㅣ실행코드가 저장된 메모리의 주소를 가리키는 레지스터로 프로그램의 실행이 진행됨에 따라 자동으로 증가하고 프로그램의 실행 순서가 변경되는 제어문이 실행될때 자동으로 변경괸다. 그래서 직접 접근해서 값을 저장하거나 읽거나 하는 일이 없기 때문에 응용 프로그램에서는 손 댈 일이 없는 레지스터이다. EFLAGS FLAGS 비타 단위의 플래그 들을 저장하는 레지스터로 아주 특별한 용도로 사용된다.

0x03. 어셈블리 명령어의 구성

– 어셈블리는 어셈블리어라고도 부르는데 이 어셈블리어는 명령어들의 조합이다. 인텔 CPU 안에는 이 명령어들이 회로로 구현되어 있어서 어셈블리 코드를 실행할 수 있다. CPU는 2진수로 모든 것을 처리하는데 어셈블리 명령어들도 2진수로 되어 있다. 하지만 2진수로 된 것

알아보기가 힘들어 mov, add와 같은 형태로 변환하여 보여진다. 아래 그림을 보자.

명령어 다음에 오는 레지스터 이름이나 값들은 operand라고 한다. mov %eax, %ebx에서 %eax 를 제1오퍼랜드, %ebx를 제2오퍼랜드라고 한다. mov %eax, %ebx는 C언어로 보면 ebx = eax의 경우와 같다. eax에 저장된 값을 ebx에 할당(assignment)한다.(특정 장소(주로 메모리상에서)에서 특정 장소(주로 레지스터)로 데이터를 읽어 와서 적재(load)).

‘L1:‘과 같은 명령은 직접적으로 기계어 코드로 번역되지 않고 분기명령(jmp)등에서 참조될 때에, 번지의 계산에 사용된다.

0x04. 주소 지정 방식의 이해

– 어셈블리는 메모리를 직접 다룰 수 있다는 점에서 우리가 어셈블리를 배우는 큰 이유가 될 수 있다. 이 메모리를 다루기 위해서 다양한 주소 지정방식이 있는데 어떤식으로 주소를 사용하고, 참조하는지 확인할 필요가 있다. 참고로 ‘0x04’에서 예를 들었던 ‘mov %eax,%ebx’의 경우는 레지스터 어드레싱(register addressing)이다.

1. 즉시 지정방식(immediate addressing)

– mov $0x1, %eax : eax에 (16진수)1을 값을 넣는(할당) 방식이다.

– 이렇게 메모리(기억장치)의 주소의 내용을 꺼내지 않고 직접 값을 대응시키는 방식을 즉 시지정방식이라고 한다.

2. 레지스터 지정방식(register addressing)

– mov %esp, %ebp : 레지스터 ebp에 레지스터 esp의 값을 넣는다.(할당 개념)

나중에 알 수 있겠지만, 위의 명령은 스택포인터를 베이스 포인터에 넣는 명령으로 함수가 시작될때 ebp의 값(일종의 시작기준점)을 정하는 명령이다.

– 레지스터에서 직접 레지스터로 값을 대응시키는 방식을 레지스터 지정방식이라고 한다.

– 속도는 빠르지만 레지스터의 크기(32비트)로 인해 크기가 제한된다.

3. 직접 주소 지정방식(directly addressing)

– mov %eax, $0x80482f2 : 주소 0x80482f2에 있는 값을 eax에 할당한다.

– 가장 일반적인 주소지정방식이며, 메모리의 주소를 직접 지정해서 바로 찾아오는 방식이 다. 즉 eax레지스터에 0x80482f2주소의 내용을 로드(load)한다는 의미이다.

4. 레지스터 간접 주소 지정 방식

– mov (%ebx), %eax

: ebx의 값을 주소로 하여(간접적으로) eax레지스터에 할당

– ‘( )’가 들어간다면 간접 지정이라고 볼 수 있다. ‘( )’의 의미는 괄호 안에 들어간 값의 주소이다.

5. 베이스 상대 주소 지정 방식

– mov 0x4(%esi), %eax

: esi레지스터에서 4(byte)를 더한 주소의 값을 eax레지스터에 할당한다.

– 보통 레지스터의 크기가 4byte이기 때문에 레지스터 다음 주소를 의미한다. 문자열 열산이나 메모리 블록 전송등에 나오는 방식이다.

0x05. 어셈블리어 명령어 정리

0x06. 어셈블리 명령어 상세

– 명령어의 분류

1) 데이터 이동 : mov, lea

2) 논리, 연산 : add, sub, inc, dec

3) 흐름제어 : cmp,jmp

4) 프로시져 : call, ret

5) 스택조작 : push, pop

6) 인터럽트 : int

1) 데이터 전송

1. mov (move data)

– 형식 : mov SOURCE, DESTINATION

– 기능 : SOURCE위치에 들어있는 데이터를 복사하여 DESTINATION위치에 저장.

– 원칙 : 메모리와 레지스터(모든 연산은 레지스터에 저장된뒤 이루어진다.) 사이의 데이터 이동, 레지스터와 레지스터 사이의 데이터 이동이나 값을 메모리나 레지스터에 대 입할 때 사용한다. (SOURCE와 DESTINATION의 크기가 동일해야 한다.)

! DESTINATION 레지스터가 CS가 될수 없다.(프로그램실행위치가 변경되기때문)

(CS의 변경은 int, jmp, call, ret등의 명령으로 가능)

! SOURCE와 DESTINATION이 전부 메모리를 가르칠수 없다. (설계상 불가능)

! SOURCE가 직접지정방식일경우에는 DESTINATION은 CS일 수 없다.

2. lea

– 형식 : lea SOURCE, DESTINATION

– 기능 : SOURCE OPERAND에서 지정된 주소를 DESTINATION으로 로드한다.

LEA의 주된 용도는 매개변수나 지역변수의 주소를 얻어오는 것이다.

예를 들어 C언어에서 지역변수나 매개변수에 &연산자를 사용한다면 컴파일러는

lea명령어를 생성한다.

– 원칙 : SOURCE OPERAND는 메모리에 위치해야하며, 변경될 주소는 index register나 DESTINATION에 정의된 주소여야 한다.

2) 논리, 연산 : add, sub, inc, dec

1. add

– 형식 : add opr1, opr2

– 기능 : opr2의 내용에 op1의 내용이 더해져서 그 결과를 opr2에 저장.

– 원칙 : ! 두 개의 오퍼랜드 모두에 메모리로 조합되는 것은 불가능.

2. sub (subtract)

– 형식 : sub opr1, opr2

– 기능 : 첫번째 오퍼랜드로 부터 2번째 오퍼랜드 의 내용을 뺀 다음 결과를 첫 번째 오퍼

– 원칙 : ! 메모리끼리는 뺄셈을 할수 없다.

3. inc (Increment)

– 형식 : inc DESTINATION

– 기능 : DESTINATION을 1 증가시키고 결과값을 다시 저장

4. dec (decrement)

– 형식 : dec DESTINATION

– 기능 : DESTINATION을 1 감소시키고 결과값을 다시 저장

3) 흐름 제어 : jmp, cmp

– 형식 : jmp proc

– 기능 : 프로그램의 흐름을 바꿀 때 사용. proc의 주소로 가서 그곳의 명령어를 실행.

if/else문, loop문(루프가 아직 끝나지 않았을때, 처음위치로 돌아가기 위해)

등에서 나타난다.

2. cmp

– 형식 : cmp value, value

ex) cmp %eax, 0 (eax레지스터의 값을 0과 비교한다.)

je start (비교 결과가 같다면 start로 분기한다.)

(같지 않다면 je 다음에 오는 명령어를 실행한다.)

– 기능 : 두값을 비교하고 비교결과에 따라 분기한다. 보통 레지스터나 메모리 및 숫자의 크기를 비교한다. cmp 명령어는 Zero, Sign, Overflow 등의 플래그를 set or clear 한다. 이 플래그의 결과에 의해서 Jcc 명령어들은 분기할 것인지를 결정한다. 보통 CMP 명령어 다음에 JE, JNE 등의 jmp관련 명령어가 위치한다.

– 원칙 : cmp 명령은 혼자 사용되지 않고 언제나 조건 점프 명령어나 조건 이동(mov) 명령어와 함께 사용된다.

– 조건 점프 명령어 : cmp 명령어의 결과에 따라 점프하는 명령어.

* 참고 *

Unsigned 계열 (부호가 없는 값)

je : jump equal – 비교 결과가 같을 때 점프

jne : jump not equal – 비교 결과가 다를 때 점프

jz : jump zero – 결과가 0일 때 점프, je와 같음. (cmp 명령에서 결과가 같으면 0을 출력)

jnz : jump not zero – 결과가 0이 아닐 때 점프

ja : jump above – cmp a, b에서 a가 클 때 점프

jae : jump above or equal – 크거나 같을 때 점프

jna : jump not above – 크지 않을 때 점프

jnae : jump not above or equal – 크지 않거나 같지 않을 때 점프

jb : jump below – cmp a, b에서 a가 작을 때 점프

jbe : jump below or equal – 작거나 같을 때 점프

jnb : jump not below – 작지 않을 때 점프

jnbe : jump not below or equal – 작지 않거나 같지 않을 때 점프

jc : jump carry – 캐리 플래그가 1일 때 점프

jnc : jump not carry – 캐리 플래그가 0일 때 점프

jnp/jpo : jump not parity / parity odd – 패리티 플래그가 0일 때 / 홀수일 때 점프

jp/jpe : jump parity / parity even – 패리티 플래그가 1일 때 / 짝수일 때 점프

jecxz : jump ecx zero – ecx 레지스터가 0일때 점프

Signed 계열 (부호가 있는 값)

jg : jump greater – cmp a, b에서 a가 클 때 점프

jge : jump greater or equal – 크거나 같을 때 점프

jng : jump not greater – 크지 않을 때 점프

jnge : jump not greater or equal – 크지 않거나 같지 않을 때 점프

jl : jump less – cmp a, b에서 a가 작을 때 점프

jle : jump less or equal – 작거나 같을 때 점프

jnl : jump not less – 작지 않을 때 점프

jnle : jump not less or equal – 작지 않거나 같지 않을 때 점프

jo/jno : jump overflow / not overflow – 오버플로 플래그가 1일 때 / 0일 때 점프

js/jns : jump sign / not sign – 사인(부호) 플래그가 1일 때(음수) / 0일 때(양수) 점프

조건 점프 명령을 조합하여 if ( a > b ), for, while등의 조건문 구현

4) 프로시져 : call, ret

1. call

– 형식 : call Target

– 기능 : 스택 상에서 CS를 다음에 오는 명령의 오프셋 어드레스를 PUSH하고 target으로 이동한다. 즉, 다른 함수로 제어를 옮긴다는 뜻이다. CALL 명령어 다음에 오는 명령어의 주소를 스택에 PUSH하고 주어진 주소로 제어를 옮긴다는 뜻(EIP를 변경시킴)

# CALL명령은 CALL명령 다음위치에 있는 명령의 주소를 스택에 push한다.

2. ret (return)

– 형식 : ret

– 기능 : 호출된 함수에서 호출한 함수로 복귀. esp에 있는 값을 꺼내서(pop) EIP레지스터에 할당한다. 즉, call명령 당시 push되었던 주소를 pop하여 eip에 넣는 것이다.

5) 스택조작 : push, pop

1. pop

– 형식 : pop DESTINATION

– 기능 : 스택 맨 윗부분(top)에서 하나의 워드를 DESTINATION에 로드(load)그리고 스택포인터는 그 바로 전의 데이터를 가리킨다(point).

2. push

– 형식 : push DESTINATION

– 기능 : 메모리상에 설정된 스택이라는 공간에 데이터를 저장한다. 스택의 가장 윗부분에

데이터를 저장. 스택 포인터(esp)도 워드크기만큼 증가한다.

6) 인터럽트 : int

– 형식 : int (interrupt-type)

– 기능 : 운영체제에 할당된 인터럽트 영역을 system call.

0x07.참조 사이트 및 문서

1. “김병희”님이 쓰신 문서. (제목이 나와있지 않네요)

2. Lecture Note in Assembly Language Written by Han, Kwang-Rok

3. 블루님의 매크로 어셈 이야기

4. Just Enough Assembly Language to Get By, Part 1,2 by Matt Pietrek

5. 김성훈님의 C 프로그래머가 알아야 할 것들 – Chapter 7 어셈블리

6. 유용수님의 어셈블리 강좌

7. 김영빈님의 “헥커가 되자”

8. C를 어셈블리어로

9. Assembly Tutor

script async src=”//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”>

어셈블리어 입문하기

728×90

오늘은 어셈블리어를 처음 사용해볼껀데요

사용전에!!!

어셈블리어가 무엇인지!

저급언어 고급언어가 무엇인지!

그리고 컴파일러와 어셈블러의 특징이 무엇인지 알아보도록 하겠습니다.

그럼 Start🙉

https://joone.net/tag/assembly-language/ (출처)

어셈블리어란?

어셈블리어(assembly language)또는 어셈블러 언어(assembler language)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어이다.(H/w와 관련이 많음, 기계어와 가까움)

컴퓨터 구조에 따라 사용하는 기계어가 달라지며, 따라서 기계어에 대응되어 만들어지는 어셈블리어도 각각 다르게 된다. 컴퓨터 CPU마다 지원하는 오퍼레이션의 타입과 개수는 제각각이며, 레지스터의 크기와 개수, 저장된 데이터 형의 표현도 각기 다르다. 모든 범용 컴퓨터는 기본적으로 동일한 기능을 수행하지만, 기능을 어떤 과정을 거쳐 수행할지는 다를 수 있으며, 이런 차이는 어셈블리어에 반영되게 된다. -출처 : 구글 위키백과-

컴파일러와 어셈블러의 특징

컴파일러(Compiler) 어셈블러(Assembler) – 고급 언어 프로그램을 입력 – 구문 오류 검사 – 목적코드(Object code) 생성 – 고급 언어의 한 문장은 여러 개의 기계 코드 명령어로 변경됨. – 어셈블리어를 기계어 형태의 오브젝트 코드로 해석해주는 컴퓨터 언어번역 프로그램 – 어셈블리어 프로그램을 입력함 – 하나의 어셈블리어 명령어는 하나의 기계 코드에 대응함.

어셈블리어는 기계언어와 가까운 “기호 언어” 라고도 하는데

보통 고급언어에서 한번에 계산으로 실행될 수 있는 문장이

기계어에서는 여러번에 계산을 통해 실행이 된다.

밑에 예시를 보자면,

이 문장을 고급 언어로 실행시킨다면 곧바로 되겠지만…..

어셈블리어는

이렇게 여러과정을 거쳐야 한다는 사실! (손으로 그리다 보니 삐뚤빼뚤 하네요 ㅠㅠ죄송합니다.)

고급언어와 어셈블리어의 특징

고급언어 어셈블리어 – 프로세서 종류에 상관없이 실행할 수 있다. – 프로세서에 대한 사전 지식이 필요 없다. – 문법이 간단하고 이해하기가 쉽다.(어셈블리어에 비교한 것) – 프로그램 코드의 양이 적고 디버깅이 용이하다. – 컴파일러 성능에 따라 프로그램의 성능이 용이하다. – 동일한 종류의 프로세서만 실행할 수 있다. – 프로세서에 대한 사전 지식이 필요하다. – 메모리, I/O장치, 레지스터 등의 구성요소들을 직접 다룰 수 있다. – 컴퓨터에서 실행하는 과정 등을 이해하기 쉽다. – 컴퓨터의 성능에 최적인 프로그램을 작성할 수 있다.

어셈블러 종류

☑ MASM -윈도우

☑ GAS – 리눅스/ 유닉스

☑ NASM – 윈도우, 리눅스, 맥

☑ SASM – 윈도우, 리눅스

이중에서 저는 SASM로 실습을 해볼 것이기 때문에 간단히 SASM에 대한 특징을 간단히 설명해드릴께요!

열어주세요 ▼

더보기 – 통합 개발 환경이다. (도구로 쓰임) – GUI와 CUI를 같이 사용한다. – 공통 매크로 함수를 지원한다. => 화면 및 키보드 입출력을 관련하여 서로 다른 운영체제 서비스 부분을 추상화 한다. – 인텔 표기법을 사용한다. – 코드는 특수한 경우를 제외하고 대소문자를 구분하지 않는다. – 주석은 세미콜론을 (;) 사용한다.

여기까지! 어셈블리어와 어셈블리 그리고 컴파일에 대해 알아보았구요!

고급언어와 저급언어도 알게되었죠?ㅎㅎ

다음 포스팅은 SASM로 실제 어셈블리어 언어를 배우는 글을 올려보도록 할께요

그럼 다들 수고 하세용!

반응형

키워드에 대한 정보 어셈블리어 코딩

다음은 Bing에서 어셈블리어 코딩 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어]

  • 리버싱
  • 포너블
  • 어셈블리
  • 어셈블리언어
  • 어셈블리어
  • Computer Security
  • 정보보안
  • Education
  • 보안공부
  • 해킹공부
  • IT
  • 지식정보
  • 지식공유
  • 교육
  • 프로그래밍
  • 프로그래밍언어
  • C언어
  • 악성코드취약점분석

리버싱과 #시스템 #해킹을 #공부하려면 #꼭 #알아야하는 #어셈블리어의 #기초[어셈블리어]


YouTube에서 어셈블리어 코딩 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 리버싱과 시스템 해킹을 공부하려면 꼭 알아야하는 어셈블리어의 기초[어셈블리어] | 어셈블리어 코딩, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

Leave a Comment