안녕, 세상!ASM x86_64에서

여보게, 저기!
올해 나는 대학에서 컴퓨터 조직 II를 배웠다.지금까지 저는 어셈블리 언어에서 어떻게 계산하는지에 푹 빠졌습니다. 여러분과 제 지식을 나누고 싶습니다.
아마도 이것은 시리즈가 될 것이다. 왜냐하면 나는 내가 정말 이 주제에 매료되었다는 것을 발견했기 때문이다. 나는 많은 사람들이 프로그래밍이 이 정보를 어떻게 처리하는지 더욱 잘 이해할 것이라고 생각한다.
하지만 우선 해야 할 일은

❓ ASM이란 무엇입니까?



ASM, Assembler(또는 assembly)의 줄임말은 C, Java, Go 또는 다른 언어와 같은 독특한 언어가 아니라 코드를 기계 언어로 바꾸는 프로그램이다.이것은 서로 다른 유형의 기계가 모두 어셈블리 언어를 가지고 있다는 것을 의미한다.예를 들어, Intel 및 AMD 프로세서 아키텍처(x86_64)를 위한 어셈블러가 있고 ARM 아키텍처도 있습니다.
이 강좌는 Intel을 위한 아키텍처

🔧 우리 뭐 쓸까?



이 간단한 프로그램에 대해 우리는 NASM과 당신이 좋아하는 모든 텍스트 편집기를 사용할 것입니다.내 예에서, 나는 VS 코드를 사용할 것이다. 왜냐하면 그것은 괜찮은 플러그인이 있기 때문이다.
Debian 시스템(Ubuntu, PopOs!, Linux Mint 등)에 NASM 설치
sudo apt-get update -y
sudo apt-get install -y nasm

나는 linux 시스템에서만 이 예를 보여 준다. 맥의sys 호출이 다르기 때문에 이 예는 그 시스템에서 작용하지 않는다. (나를 믿어라. 이 글도 맥을 겨냥한 것이다...)


🏗️ ASM 프로그램의 구조


네, 이제 어셈블러와 텍스트 편집기나 IDE가 있습니다.이제 어떡하지?
새 파일을 만들어서 HelloWorld라고 명명합시다.회사 명

지금 우리는 빈 서류가 생겼다.우리는 이 파일을 어떻게 사용하는지 확인해야 한다.ASM에는 파일당 4개의 섹션이 있습니다.이 부분을 정의하지 않아도 항상 존재합니다.그러나 만약 당신이 하나를 필요로 한다면, 당신은 반드시 이렇게 해야 한다.
네 가지 섹션은 다음과 같습니다.
  • .데이터: 전역 초기화 변수
  • 를 어디에서 설명할 것인가
  • .rodata: 전역 초기화 상수 없음
  • 을 어디서 설명할 것인가
  • .bss: 우리는 어디에서 우리의 전체 초기화 변수를 성명할 것입니까
  • .텍스트: 코드를 정의하는 방법
  • 👏 손대다


    알겠습니다. Hello World를 인쇄하는 CLI 프로그램을 구축하려고 합니다.듣기에 상당히 쉽다.그러나 이 점을 하기 위해서, 우리는 프로세서에 통지해야 한다. 우리는'스타트'라는 함수를 전체 시스템에 대해 전역적으로 명명할 것이다.그래서 우리는 우리의 것을 추가했다."start"함수가 있는 텍스트 바이트와 바이트 밖의 전역 문장입니다.이렇게

    우리는 어떤 화려한 C 함수도 사용하고 싶지 않고 다른 고급 언어 함수도 사용하고 싶지 않기 때문에 시스템 호출에 의존할 것이다.
    깊이 파고들지 않고 시스템 호출은 운영체제에 대한 호출일 뿐이다.유닉스 시스템에서 0x80 인터럽트를 호출하고 인터럽트에 처리하고자 하는 매개 변수를 전달해야 합니다.
    우리가 사용할 함수(sys_write)의 경우 4개의 매개변수 수신을 중단합니다.
  • 함수 번호(RAX)
  • RBX
  • 우리가 실행하고자 하는 메모리 방향(RCX)
  • 바이트 단위 메시지 크기(RDX)
  • RAX, RBX, RCX, RDX는 우리가 사용할 다용도 레지스터일 뿐입니다. 저는 이 시리즈의 진일보한 장에서 설명할 것입니다.지금 나한테 얘기해.
    먼저 메시지를 정의하고 int 0x80을 호출합니다.

    여기 새로운 정보가 많아요.우리 한 줄씩 걷자.
    section .data
    
    이게 저희가'안녕 세상'을 정의해야 되는 부분이에요.문자열 변수.그것은 이미 초기화되었기 때문에, 우리는 에서 성명한다.데이터
    msg: DB 'Hello World!', 10
    
    이것은 우리의 새 줄이다.이것은 이름 msg에서 설명한 것입니다. 우리는 DB (define byte) 로 그것을 초기화하고, 표시된 문자와', 10'을 우리의 문자로 합니다.내가 너희들에게 이 단계에서 얻고 싶은 것은 모든 문자가'안녕, 세상!'을 구성하는 것이다.바이트의 메모리를 차지하다.따라서 DB를 사용하려면 프로세서에 13바이트를 사용하는 메모리 슬롯(계산 공간과 문자)을 제공해야 합니다.
    msgSize EQU $ - msg
    
    이거 좀 어려워요.우리는 변수가 msgSize를 호출하는 것을 설명하고 있습니다. 이것은 Hello World의 오른쪽에 들어갈 것입니다!($) 그리고 msg 변수가 시작될 때의 주소를 빼줍니다.이렇게 해서 msg에 사용할 바이트를 남겨주셨어요.
    우리는 우리의 소식이 있으니, 지금 바로 나타내자!

    다시 한 번, 여기서 무슨 일이 일어났는지 설명해 봅시다
        mov rax, 4          ; function 4
        mov rbx, 1          ; stdout
        mov rcx, msg        ; msg
        mov rdx, msgSize    ; size
        int 0x80
    
    인텔은 대부분의 경우 매우 이상한 업무 방식을 가지고 있다.따라서 한 줄의 텍스트는 다시 네 부분으로 구분된다
       mov A, B   ; comments
    
  • Mov: 요소를 B에서 A로 이동하는 명령어
  • A: 운명 레지스터/스토리지
  • B: 레지스터/메모리
  • 주석: 여기서 주석은: p
  • 따라서 우리가 여기서 하는 것은 숫자 4를 RAX 레지스터로 이동하는 것이다. (sys\u write는 UNIX의 함수 4이기 때문이다.)우리는 숫자 1을 RBX로 이동합니다(stdOUT 대표).그런 다음 msg를 정의하는 메모리는 RCX에 저장되고 크기는 RCX에 저장됩니다.int 0x80을 호출함으로써, 우리는 0x80이 우리에게 던진 모든 매개 변수를 처리하고, 실행해야 할 작업을 중단할 것을 요구합니다.

    우리의 마지막 단계는 이 계획에서 물러나는 것이다.너는 어떻게 생각하니?이것은 다른 시스템 호출이 필요하다.이 경우, 우리의 함수는 숫자 1 (exit), 매개 변수는 0 (이것은 우리가 되돌려주고 싶은 숫자이기 때문이다. 0 은 프로그램이 성공적으로 실행되었음을 나타내고, 1 은 성공적으로 실행되지 않았음을 나타낸다)
        mov rax, 1          ; function 1
        mov rbx, 0          ; code
        int 0x80
    

    🔗 조립 및 링크


    파일을 HelloWorld로 저장합시다.asm와 종착역으로 가세요.
    NASM을 설치한 경우 파일을 저장하는 폴더로 이동합니다.asm 파일을 조립하고 연결합니다.
    Linux:
    nasm -f elf64 -g -F DWARF helloWorld.asm
    ld -e start -o helloWorld helloWorld.o
    ./helloWorld
    
    오늘은 여기까지.너는 반드시 너의 단말기에서'안녕한 세상'이라는 소식을 받아야 한다.

    전체 코드를 보려면 저장소 참조: Hello World!

    좋은 웹페이지 즐겨찾기