나빌로스를 한답시고 보면서
정작 어셈블리 공부를 제대로 안하고 이상한걸 보고 있었다가 다시 돌아왔다.
너무 깊이 배울 필요는 없어서 자료 찾다보니
kldp의 자료가 적당할거같고
mov는 어떻게 쓰고, jmp는 어떻게 쓰고 하는 자질구래한 내용들 많은 강좌보다는
섹션이 뭐고 다 포함하고
이 내용을 따라했다.
https://wiki.kldp.org/HOWTO/html/Assembly-HOWTO/x848.html
소개
마침내 때가 왔다. 여러분이 아직도 이 문서를 읽고 있으며, 여전히 어셈블리로 무언가를 만들겠다는 광기어린(!) 생각을 가지고 있다면 (여기까지 읽은 사람이라면, 정말 어셈블리 팬임에 틀림
wiki.kldp.org
프로그램 레이아웃
- .text 섹션 : 작성한 코드
- .data 섹션 : 초기화된 데이터
- .bss 섹션 : 초기화 되지 않은 데이터
NASM 코드 helloworld
section .data ; 섹션 .data 선언
msg db "hello, world!", 0xa ; 출력할 문자열
len equ $ - msg ; 문자열 길이
section .text ;여기부터 .text 섹션
global _start ;ELF링커나 로더에게 프로그램 엔트리포인터알려줌.보통 _start
_start:
mov edx, len ; 시스템콜의 세번째 인수, 출력할 메시지 길이 가져옴
mov ecx, msg ; 시스템콜의 두번째 인수, 출력할 메시지 포인터 가져옴
mov ebx, 1 ; 시스템콜의 첫번째 인수, 파일 디스크립터 전달.
mov eax, 4 ; eax 레지스터에 시스템 콜번호 전달. 4번은 sys_write
int 0x80 ;커널 호출
; 출력 완료 후 exit 호출
mov ebx, 0 ; exit 코드로 0을 준다.
mov eax, 1 ;시스템 콜 1번(sys_exit)
int 0x80 ;커널 호출
실행 결과
kldp 내용만 봐도 뭔지 대강알긴 하겠지만 설명이 좀 부족해보인다
여기보다는 이쪽 튜토리얼이 예제나 설명이 자세하다.
NASM Assembly Language Tutorials - asmtutor.com
~$ nasm -f elf helloworld-input.asm ~$ ld -m elf_i386 helloworld-input.o -o helloworld-input ~$ ./helloworld-input Please enter your name: Daniel Givney Hello, Daniel Givney
asmtutor.com
lesson 1 예제를 보면
직접 어셈블리어로 하드웨어를 제어하고 싶을때 EAX 레지스터에다가 함수번호(오퍼레이션 코드)를 넣고,
나머지 레지스터에다가 필요한 값을 넣은 다음에, int 명령으로 소프트웨어 인터럽트를 주면 지정한 함수가 호출된다.
sys_exit()는 EAX=1을
sys_write()는 EAX=4 그리고 EBX, ECX, EDX에 필요한 값을 넣어주면 된다.
; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
SECTION .data
msg db 'Hello World!', 0Ah ; assign msg variable with your message string
SECTION .text
global _start
_start:
mov edx, 13 ; number of bytes to write - one for each letter plus 0Ah (line feed character)
mov ecx, msg ; move the memory address of our message string into ecx
mov ebx, 1 ; write to the STDOUT file
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 80h
위에서 설명한대로
SECTION .data
데이터 섹션 그러니까 초기화 되는 변수 부분을 나타내는데
msg라는 변수에다가 'hello world'를 담는건 알겠지만 왼쪽에 db와 우측에는 ,0ah가 존재한다.
이게 뭐소리인가 찾아보니
db는 바이트 데이터 형을 의미한다하고,
다른데도 찾아보니 msg에 바이트 단위 배열로 넣기 위한 자료형 선언한다는 의미라한다.
ref : https://velog.io/@kyoung99u/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC-%EC%96%B8%EC%96%B4
[Assembly] 어셈블리 기초
변수 어셈블리 프로그램에서 변수를 어떻게 사용할까? 어셈블리 프로그램에서는 타 프로그램과 같이 변수를 정의하여 사용하는데, 변수는 변수명과 데이터형, 초기값을 가진다. 0806 어셈블리언
velog.io
그러면 ,0ah는
쿼라에 질문올라온게 있긴한데
답변한 사람 말로는
0xA는 라인피드
0xD는 캐리지 리턴이라고 설명하고 있다.
그러면 0xAh는 뒤에 h가 붙어있는데 이건 뭔소린가 싶긴한데 설명이없다.
https://www.quora.com/What-is-the-meaning-of-0ah-0dh-in-assembly-language-for-displaying-any-message
What is the meaning of 0ah, 0dh in assembly language for displaying any message?
Answer (1 of 4): As everyone else answered, 0xA linefeed (\n), 0xD carriage return(\r), but have you wondered why is this two different notion in assembly? why did the carriage return and line feed was different back then ?? in high level languages when we
www.quora.com
여길 보니 0ah가 아스키 코드로 라인피드가 맞다고 하는걸 보니 답변자가 빠트린가 보다
https://www.sluiceartfair.com/2018/contributing/what-is-0ah-in-assembly/
What is 0AH in assembly? – Sluiceartfair.com
What is 0AH in assembly? 0Ah is the hexadecimal constant for the Line Feed character in ASCII, often abbreviated LF. 24h is the hexadecimal constant for the ‘$’ character in ASCII. What is carriage return in assembly language? Carriage Return Character
www.sluiceartfair.com
int 80h는 소프트웨어 인터럽트를 발생시키는 어셈블리 코드라고한다.
https://second.wiki/wiki/int_80h
Int 80h
Int 80h
second.wiki
일단 어셈블리와 링커를 돌린후 실행하보면 생각한데로 출력은 잘되는데 세그먼테이션 폴트가 뜬다.
이 문제는 다음 레슨에서 설명하는데
~$ nasm -f elf helloworld.asm
~$ ld -m elf_i386 helloworld.o -o helloworld
~$ ./helloworld
Hello World!
Segmentation fault
레슨 2 : 프로그램을 제대로 종료시키자
레슨 1에서는 어셈블리어로 sys_write 시스템 콜을 써서 출력을 시켰는데 이번 레슨에서는 sys_exit에 대해서 보자
설명이 쭉 있는데, 결국에는 모든 프로그램은 메모리를 공유하고 있다보니 global _start에서부터 순차적으로 실행해주는데 어디서 끝낼지 커널한태 알려주지 않으면 구현하지 않은 다음 주소에 있는것도 실행하게 되고 이게 세그먼테이션 폴트의 원인이 된다고 한다.
sys_exit를 쓰기 위해선
EBX에 0을 전달하도록 0을
EAX에 sys_exit를 호출하는 1을 넣으면 되서 코드는 이렇게 된다고 말한다.
; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
SECTION .data
msg db 'Hello World!', 0Ah
SECTION .text
global _start
_start:
mov edx, 13
mov ecx, msg
mov ebx, 1
mov eax, 4
int 80h
mov ebx, 0 ; return 0 status on exit - 'No Errors'
mov eax, 1 ; invoke SYS_EXIT (kernel opcode 1)
int 80h
정상적으로 프로그램을 종료시켜서인지 세그먼테이션 폴트가 뜨지 않고 잘 끝낫다!
'컴퓨터과학 > 임베디드' 카테고리의 다른 글
아두이노회로만들기 - 5. L298N DC 모터드라이버 (0) | 2022.08.25 |
---|---|
아두이노회로만들기 - 4. 태양광 충전, 블링크 회로 (0) | 2022.08.24 |
조금씩 임베디드 - 9. 링커 스크립트 (0) | 2022.08.17 |
조금씩 임베디드 - 8. ARM 어셈블리어 (0) | 2022.08.17 |
조금씩 임베디드 - 7. C언어, 어셈블리어 최적화 기법 (0) | 2022.08.17 |