前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >汇编学习(1),汇编之helloworld

汇编学习(1),汇编之helloworld

作者头像
一只小虾米
发布2022-11-28 15:47:31
7610
发布2022-11-28 15:47:31
举报
文章被收录于专栏:Android点滴分享Android点滴分享

本篇介绍

本篇作为汇编系列的开篇,就先研究下汇编如何写helloworld。

内容介绍

首先新建一个asm,写入内容如下:

代码语言:javascript
复制
    ; hello.asm
    section .data
    msg db "hello, world",0
    section .bss
    section .text
    global main
main:
    mov rax,1
    mov rdi,1
    mov rsi, msg
    mov rdx,12
    syscall
    mov rax,60
    mov rdi,0
    syscall

代码的含义稍后介绍。 再新建一个makefile文件,内容如下:

代码语言:javascript
复制
hello: hello.o
    gcc -o hello hello.o -no-pie
hello.o: hello.asm
    nasm -f elf64 -g -F dwarf hello.asm -l hello.lst

makefile可以这样看,目标hello依赖hello.o, 而hello.o又依赖hello.asm, 如果hello.asm的修改时间大于hello.o,那么hello.o下一行的命令就需要执行。

nasm就是汇编器,如果系统没有的话,需要安装一下:

代码语言:javascript
复制
sudo apt install build-essential nasm

-f elf64用来指定输出文件的格式是elf64,-g表示需要包含debug信息,-F dwarf用来指定debug信息格式是dwarf,-l用来生成机器码和汇编的对应文件。 这时候执行make,就会看到生成了hello程序。

代码语言:javascript
复制
-rwxrwxr-x 1 shanks shanks 16192 11月 15 00:38 hello*
-rw-rw-r-- 1 shanks shanks   190 11月 15 00:38 hello.asm
-rw-rw-r-- 1 shanks shanks   862 11月 15 00:38 hello.lst
-rw-rw-r-- 1 shanks shanks  2240 11月 15 00:38 hello.o
-rw-rw-r-- 1 shanks shanks   139 11月 15 00:36 makefile

直接执行hello, 就会看到如下输出:

代码语言:javascript
复制
shanks@shanks-ThinkPad-T460s:~/Documents/04workspace/02asm/ch01$ ./hello
hello, world

接下来看下代码的含义吧。 汇编程序一般由data,bss,text 3个段构成, 前面加section就是定义这是某个段。 在section .data段用来定义变量,格式如下

代码语言:javascript
复制
<variable name> <type> <value>

类型如下:

type

length

name

db

8 bits

Byte

dw

16 bits

Word

dd

32 bits

Double word

dq

64 bits

Quaword

名字用来引用对应内存的首地址,这样实际上可以分配的空间就可以是多个。比如代码中的msg,指向的是h地址,而h又是整个字符串的首地址,这样用msg就可以访问整个字符串了。可能已经注意到了在代码中,后面还加了一个0,整个主要是为了表示字符串结束了,并无其他含义。

text段也可以定义常量,格式如下:

代码语言:javascript
复制
<constant name> equ <value>

比如
pi equ 3.14

section .bss用来定义没初始化的变量,格式如下:

代码语言:javascript
复制
<variable name> <type> <name>

比如下面是定义了一个 20字的数组
dArray resd 20

类型如下:

type

length

names

resb

8 bits

Byte mov rax,1

代码语言:javascript
复制
mov rdi,1
mov rsi, msg
mov rdx,12

resw|16 bits|Word resd|32 bits|Double word resq|64 bits|Quaword

section .txt就是代码段了,名字后加冒号就是定义了一个label,这样在代码中就可以作为跳转目标了。 再继续看显示代码:

代码语言:javascript
复制
    mov rax,1
    mov rdi,1
    mov rsi, msg
    mov rdx,12
    syscall

rax 是系统调用编号,1对应的正好是write,rdi是write的第一个参数,也就是显示的目的,1对应的是标准输出,rsi是需要显示的字符串,对应write的第二个参数,rdx是write的第三个参数,也就是显示的数量。 syscall就是触发系统调用。

代码语言:javascript
复制
    mov rax,60
    mov rdi,0
    syscall

接下来就是程序退出了,60对应的是exit,rdi是返回值。 这儿就能发现,系统调用的传参顺序是rdi,rsi,rdx,对应的系统调用编号查询网址。 最后再看下生成的lst文件:

代码语言:javascript
复制
     1                                      ; hello.asm
     2                                      section .data
     3 00000000 68656C6C6F2C20776F-         msg db "hello, world",0
     3 00000009 726C6400           
     4                                      section .bss
     5                                      section .text
     6                                      global main
     7                                  main:
     8 00000000 B801000000                  mov rax,1
     9 00000005 BF01000000                  mov rdi,1
    10 0000000A 48BE-                       mov rsi, msg
    10 0000000C [0000000000000000] 
    11 00000014 BA0C000000                  mov rdx,12
    12 00000019 0F05                        syscall
    13 0000001B B83C000000                  mov rax,60
    14 00000020 BF00000000                  mov rdi,0
    15 00000025 0F05                        syscall

最左边是地址,中间是机器码,右边是汇编指令。

这样就完成了汇编helloworld的学习了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-11-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本篇介绍
  • 内容介绍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档