기계어는 데이터 타입을 어떻게 알까?

김동현·2023년 11월 16일

Question

목록 보기
4/15
post-thumbnail

저수준 언어

  • 컴퓨터가 이해할 수 있는 0과 1로 이루어진 명령어이다.
  • 저급 언어는 명령어로 이루어져 있다!!
  • 저급 언어는 두 가지로 나뉜다.
  1. 기계어 → 0과 1의 명령어 비트로 이루어진 언어이다.
    1. 0과 1로 이루어진 기계어는 가독성이 떨어지고 길어지기 때문에 십육진수를 사용하여 표현하기도 한다.
    2. 0과 1로 이루어져 있는 기계어는 인간이 해석하기에 너무 어렵다.
  2. 어셈블리어 → 0과 1로 이루어진 명령어(기계어)를 인간이 읽기 편한 형태로 번역한 언어이다.

Ex)
0101 0101 → push rbp
0101 1100 → pop rbp
1100 0011 → ret

// C언어
#include<stdio.h>

int main() {
    int a = 1; 
    int b = 2;	
    int c = a + b;
    
    printf("%d", c);
}
 // asm
 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

어셈블러

어셈블러는 어셈블리어를 기계어로 변역하고 실행 가능한 파일로 만드는 프로그램(로더)에 필요한 정보를 생성하는 역할을 한다.

어셈블러는 기계어로 번역하는 과정에서 필요한 정보를 DB에 저장하고 필요 시에 불러 사용하게 된다.

아래 어셈블리 코드는 어셈블리 실행 사이트를 들어가면 기본으로 나오는 어셈블리 코드이다.
-> Hello World를 출력하는 어셈블리 코드!

section .data   // 초기화 데이터를 선언하는 섹션
    msg db "Hello world!", 0ah
    // msg(식별자) db(바이트 정의) Hello world ,(구분자) 0ah(\n를 나타내는 ASCII코드 16진수 값)

section .text
    global _start

_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, 13
    syscall
    mov rax, 60
    mov rdi, 0
    syscall

어셈블리 언어에서 db와 같은 지시어를 사용하면 어셈블러에게 메모리 공간을 예약하고 해당 위치에 특정 값이나 데이터를 저장하도록 지시한다.
그런 다음 어셈블러는 이러한 데이터 저장 명령어를 반영하는 기계어 명령어를 생성하게 된다!

위의 msg db "Hello World!", 0ah의 db 지시문은 어셈블러에게 "Hello world!"0ah 문자를 위한 메모리 공간을 예약하라고 지시하게 되고,
어셈블러는 할당된 메모리 공간에 이러한 바이트를 저장하기 위해 적절한 기계 코드 명령어를 생성하는 것이다.

어셈블리어 데이터 타입

  • mov dword ptr [ebp-8],1
  • dword는 Doble Word로 32비트 부호 없는 정수를 의미한다!

어셈블리어는 데이터 타입이 존재하지만, 우리가 알고 있는 일반적인 타입과 조금 다르다.

출처

정수형 데이터 타입

정수형 데이터 타입은 일반적으로 우리가 생각하는 숫자 값이다.

MOV AX, 10      AX 레지스터에 10을 저장해라

부동 소수점 타입

부동 소수점 타입은 실수를 저장하는 데 사용된다.
어셈블리어는 부동 소수점 타입에 대한 작업을 수행하는 명령어에 보통 F 접두사를 붙인다.

부울 값

부울 데이터 유형은 T/F를 저장하는 데 사용된다. 이는 조건문과 루프에 자주 사용된다.

CMP AX, 0;  0과 AX를 비교해라
JE is_zero; AX가 0이면, is_zero 라벨로 점프(분기처리)해라

문자 값

문자는 일반적으로 ASCII 코드의 8비트 레지스터에 저장된다.

In Assembly language, we don't have variables. We have memory. We have bytes in memory. We have words in memory. We have doublewords in memory. We have quadwords in memory. But we don't have integers, characters, floating-point numbers, or Booleans. We have only bytes, and the meaning of those bytes depends entirely on what we do with them.

Jeff Duntemann

Jeff Duntemann 선생님의 인용구를 보면 명확해 진다.
어셈블리어에는 변수란 없다.
어셈블리어는 메모리를 가지고 있다.
메모리 안에는 바이트만 가지고 있다.

전적으로 우리가 이 바이트를 어떻게 사용하느냐에 달려 있다. -> 이 바이트를 어떻게 사용하느냐에 따라 달려있다.

어떻게 사용하느냐

확신할 수는 없지만,
우리가 구현한 고급 언어가 컴파일러와 어셈블러를 거치고 나면 0과 1로 이루어진 실행 기계어가 남게 되는 데 이 기계어는 명령어로만 이루어져 있다.

-> 메모리에 데이터를 저장해라
-> 메모리에서 명령어를 가져와라
-> 명령어를 실행하기 위해 필요한 피연산자를 메모리에서 가져와라
-> 가져온 명령어를 실행해라
-> 가져온 명령어를 연산해라

이러한 과정들을 반복하는데 이를 통해 숫자를 더하고 빼고 곱하고 나누고, 문자를 자르고, 이어 붙이고 배열을 자르고, 이어 붙이는 등의 일이 일어나는 거 아닐까

컴퓨터는 덧셈 밖에 할 줄 모른다.
덧셈을 통해 사칙연산을 수행하고 연산 과정을 거친다.

문자는 아스키 코드, 유니 코드를 활용하여 처리한다.

-> 메모리에 존재하는 바이트를 어떻게 처리하느냐에 따라 그 바이트의 데이터 타입이 정해지는 것이다.

🤔 예를 들면 1000001 은 숫자로 65이고 아스키 코드로는 A이다.
이를 어떻게 활용하느냐에 따라 데이터의 유형이 정해지는 것 아닐까?!!

출력 해줘

  • C언어에서 값들을 출력 할 때 출력 형식에 따라 다른 이유도 여기 있지 않을까?
#include <stdio.h>

int main() {
    // ASCII code for 'A'
    int asciiCode = 65;

    printf("ASCII code in decimal: %d\n", asciiCode);             // 65
    printf("ASCII code in octal: %o\n", asciiCode);               // 101 -> (1 * 1) + (8 * 1) + (64 * 1) = 65
    printf("ASCII code in hexadecimal: %x\n", asciiCode);         // 41  -> (1 * 1) + (16 * 4) = 65
    printf("ASCII code in binary: ");                             // 1000001 (1 * 64) + (1 * 1) = 65
    
    // 이진수로 출력
    for (int i = 6; i >= 0; i--) {
        printf("%d", (asciiCode >> i) & 1);
    }
    printf("\n");

    return 0;
}

출처

자료형이란

✅ 자료형은 메모리에 저장된 정보를 해석하는 형식이다.

  • 널널한 개발자

참고 자료

[Assembly] 어셈블리어 기초 사용법 & 예제 총정리
https://ethan-ncs.tistory.com/8
https://ko.itpedia.nl/2019/11/11/wat-is-een-assembler-taal/
https://marketsplash.com/tutorials/assembly/assembly-data-types/
https://steemit.com/kr-dev/@codingman/c--1550796253790
https://velog.io/@jewoo/%EC%BB%B4%ED%93%A8%ED%84%B0%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%AC%B8%EC%9E%90%EB%A5%BC-%EB%8B%A4%EB%A3%B0%EA%B9%8C
https://reakwon.tistory.com/169

profile
달려보자

0개의 댓글