Hello World 에서 standard output 에 출력했다면

반대인 standard input 도 어렵지 않을 겁니다.

 

sys_read 의 시스템콜 id 는 0이고

sys_write 과 마찬가지로 3개의 인수(arguments)를

받습니다. rdi 파일 디스크립터, rsi 문자형 포인터(주소),

rdx는 바이트 사이즈입니다.

 

다른 디스트로는 모르겠는데 우분투

LTS 20.04의 경우 한글도 입력이 가능합니다.

리눅스의 내부처리 인코딩은 UTF-8 인 것으로

알고 있습니다. 어차피 syscall은 커널이

받아서 처리하는 거니까 콘솔 환경에서는

딱히 신경쓰지 않아도 됩니다.

 

그 다음에 section .bss 를 사용합니다.

.bss 는  (block starting symbol)의 약자로

아직 할당되지 않은 변수를 예약할 때

사용하는 영역입니다. bss section 이나

bss segment 라고도 합니다.

 

 

data segment 의 변수들은 초기화를

시켜줘야하는데 bss segment는 초기화 없이

사용가능합니다. 입력을 받기 위한 장소를

예약한다고 보면 됩니다.

아래의 코드에서 name resb 20은

name 이라는 심볼에 20바이트를 예약

(reserve byte) 하라는 뜻입니다.

 

section .data
    text1: db "이름이 무엇입니까?",10, "-> "
    text1_L: equ $-text1

    text2 db "안녕하세요! "
    text2_L: equ $-text2

section .bss
    name resb 20

section .text
    global _start

_start:
    call _printText1
    call _inputName
    call _printText2
    call _printName

    call _exitProgram

_inputName:
    mov rax, 0 ;syscall id sys_read
    mov rdi, 0 ;file descriptor stdin
    mov rsi, name ;reserved 20 bytes
    mov rdx, 20 ;maximum bytes
    syscall
    ret

_exitProgram:
    mov rax, 60
    mov rdi, 0
    syscall

_printText1:
    mov rax, 1 ;syscall id 1 ->sys_write
    mov rdi, 1 ;file descriptor stdout
    mov rsi, text1 ;hello world text
    mov rdx, text1_L ;byte length
    syscall
    ret ;return to where it called

_printText2:
    mov rax, 1
    mov rdi, 1
    mov rsi, text2
    mov rdx, text2_L
    syscall
    ret

_printName:
    mov rax, 1
    mov rdi, 1
    mov rsi, name
    mov rdx, 20
    syscall
    ret

 

어셈블리어 NASM

 

코드 설명

출력하는 부분은 전의 포스팅에 상세히

설명했으므로 여기서는 input 에 대해서

알아보겠습니다.

 

일단 서브루틴으로 정리한 것은

어셈블리어다 보니까 코드가 지루해지니까

이름을 하나씩 붙였습니다. 뭔가 불필요하게

느껴지지만 이것들을 자동화하는 방법도

다 있습니다. 어셈블리어는 원초적인 레고블록

같은 거라서 얼마든지 원하는 알고리즘을

구현할 수가 있습니다. 그런 것들은 차츰

알아갈테니 지금은 sys_read 시스템콜에 집중합니다.

 

무엇인가 입력을 받을 메모리를 확보하는 것은

bss section 에서 20바이트를 해놓았습니다.

C언어로 치면 변수? 배열같은 것 입니다.

여기서는 byte 단위로 하니까 알아서 판단해야 합니다.

 

section .bss
    name resb 20

 

그 다음에 입력받는 서브루틴입니다.

읽어보면 쉽게 이해할 수 있습니다.

mov rax,1

...

syscall

의 반대입니다. 출력의 반대개념으로

보면 키보드로 입력을 받아야 하고

(mov rdi, 0), 변수에 저장하고(name),

변수의 길이를 알아야 합니다.(20)

 

_inputName:
    mov rax, 0 ;syscall id sys_read
    mov rdi, 0 ;file descriptor stdin
    mov rsi, name ;reserved 20 bytes
    mov rdx, 20 ;maximum bytes
    syscall
    ret

 

출력하는 것은 변수인 name과

count 만 바꿔주면 됩니다.

 

_printName:
    mov rax, 1
    mov rdi, 1
    mov rsi, name
    mov rdx, 20
    syscall
    ret

 

*앞전 내용과 이어지니까 참고합니다.

 

 

NASM x86 어셈블리어 리눅스 Hello World - 어셈블리어 1

 

NASM x86 어셈블리어 리눅스 Hello World - 어셈블리어 1

x86 어셈블리어(Nasm) 어셈블리어는... 프로그래밍 계의 끝판왕입니다. 어려운 순서로는 기계어에 이어서 Top 2위인데, 요즘 시대에 메뉴얼로 0과1로 기계어를 작성하는 경우는 Intel 같은 CPU제조사를

digiconfactory.tistory.com

공유하기

facebook twitter kakaoTalk kakaostory naver band