汇编“Hello World"介绍帖

电脑技术 电脑技术 2660 人阅读 | 5 人回复 | 2021-10-02

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 孤星1119 于 2021-10-2 09:01 编辑

我来啦!首先给大家介绍"Hello World"在Win32 汇编怎么写。
具体用的是FASM (flat assembler),虽然流行的也包括NASM,请注意区别并不在于CPU指令部分。

譬如, FASM可能会用:
  1. entry start
  2. section '.code' code executable readable
  3. start:
  4. ......
  5. ......
复制代码


但是NASM可能会用:
  1. global    _start

  2.           section   .text
  3. _start:  
  4. ......
  5. ......
复制代码

代码还是一样的。

不管是Windows还是Linux,最基本的可执行文件结构主要由Data Segment/Section(数据段)和Code Segment/Section(代码段)组成,但是Windows还多一样才能发挥功能,就是Import Table(就是示例中下方的Kernel32.dll那些).

  1. format PE console
  2. entry start

  3. include 'win32a.inc'

  4. section '.data' readable writable

  5. _message   db 'Hello World!',13,10,0
  6. _msglen      = $ - _message1
  7. _dummy      dd ?

  8. section '.code' code readable writable executable

  9. start:

  10.         invoke  GetStdHandle, -11
  11.         invoke  WriteConsole, eax, _message, dword [_msglen], _dummy, 0

  12.         invoke  ExitProcess,0

  13. section '.idata' import readable writable

  14. library kernel32, 'KERNEL32.DLL'

  15. import kernel32,\
  16.         GetStdHandle, 'GetStdHandle', \
  17.         ReadConsole, 'ReadConsoleA', \
  18.         WriteConsole, 'WriteConsoleA', \
  19.         ExitProcess,'ExitProcess'
复制代码


参考资料

Win32 API:
https://docs.microsoft.com/en-us/windows/console/writeconsole
https://docs.microsoft.com/en-us ... eadsapi-exitprocess



另外,提醒一下,Windows的换行符是13+10(\r\n),而Linux只是10(\n)或0xA,这就是“Hello World"后面的换行符在两个操作系统都不一样的缘故。虽然如此,0x0(null)在尾端表示终止符。




最近玩Linux编程比较多,因此重点将会放在Linux的ELF64(虽然也有ELF32).

这是Linux x64的"Hello World"示例,比Windows的简单得多吧?

两者概念一样,都有一个File Descriptor,如果用作显示屏,就有StdIn和StdOut.

  1. format ELF64 executable 3

  2. segment readable executable

  3. entry $

  4.       mov     rdx,_msglen
  5.       lea     rsi,[_message]
  6.       mov     rdi,1    ; STDOUT
  7.       mov     rax,1    ; sys_write
  8.       syscall

  9.       xor     rdi,rdi
  10.       mov     rax,60   ; sys_exit
  11.       syscall

  12. segment readable writeable

  13. _message    db      "Hello World!",10,0
  14. _msglen       = $ - _message
复制代码


参考资料

Syscall: https://chromium.googlesource.co ... nstants/syscalls.md

Syscall x64 : 从0到3
Screenshot from 2021-10-02 08-30-30.png


每个不同的CPU(ARM,ARM64, x86, x64)都有不同的特定参数排列

如arg0...arg5,r开头的内部寄存器属于64位(rax),e开头的内部寄存器属于32位(eax),没有e或r开头的属于16位(ax),l结尾的属于8位(al)。

Screenshot from 2021-10-02 08-31-21.png



大家也可以在Linux终端窗口输入”man 2 <syscall function>"如图所示:

man是manual的意思吧?

Screenshot from 2021-10-02 08-46-12.png


Screenshot from 2021-10-02 08-46-28.png


当然也有网页版本:
https://www.kernel.org/doc/man-pages/



好了,大概是这么多。我的中文电脑术语有限,还望指正。谢谢大家耐心跟贴,希望你也能获益一点,Assembly(汇编)其实很吸引人的。

评分

参与人数 1钻石 +80 收起 理由
simonzhd + 80 很给力!

查看全部评分

回答|共 5 个

james007 发表于 2021-10-2 09:10:06| 字数 6 | 显示全部楼层

不懂啊,孤星
人生是一部书

simonzhd 发表于 2021-10-2 09:26:27| 字数 54 | 显示全部楼层

谢谢孤星的仔细讲解,很专业,还有“参考资料”,真是用心了,稍微有点头绪了。先收藏了,哪天空的时候在研究一下~

孤星1119 发表于 2021-10-2 09:43:04| 字数 132 | 显示全部楼层

simonzhd 发表于 2021-10-2 09:26
谢谢孤星的仔细讲解,很专业,还有“参考资料”,真是用心了,稍微有点头绪了。先收藏了,哪天空的时候在研 ...

十分感谢站长加精,而且你还收藏了,真的是宠坏我了,不过也鼓励了我应该分享知识,不仅一昧顾着积累知识为了荣誉。

孤星1119 发表于 2021-10-2 09:45:02| 字数 54 | 显示全部楼层


C其实和汇编相当接近,你慢慢来就会培养兴趣了。

孤星1119 发表于 2021-10-8 19:56:33| 字数 26 | 显示全部楼层

我另外制作的此介绍贴的HTML版本,欢迎打开看一看。


Screenshot from 2021-10-08 19-54-42.png


asm.zip (136.94 KB, 下载次数: 5)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐