在 mac OS 的装配中一步步问好世界
step by step hello world in assembly for mac OS
我在为 mac os(x86_64 体系结构)进行汇编时遇到了很多困难。我想向您介绍一个 hello world 程序的解释,如果您能给我您的反馈以及建议和解释,我将不胜感激:话虽如此,让我们进入代码。
你好世界程序
以前从未感受过Hello world的痛苦。
所以,这是我从互联网上复制粘贴的代码:
global _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
mov rsi, str
mov rdi str.len
syscall
mov rax, 0x2000001
xor rdi, rdi
syscall
section .data
str: “Hello world”,
.len: equ $ - str
所以让我为难自己:
global _main 基本上告诉链接器从哪里开始,如果我没记错的话
.text 部分告诉 OS(我猜)这是实际程序的开始。
_main 如果我没记错的话是一个函数,这似乎是函数的表示法
mov rax, 0x2000004 : 我不明白这个东西是做什么的。我在网上查了一下系统调用是如何工作的,它基本上需要一个文件代码(我认为这是下一行的 1),一个指向缓冲区的指针(这个缓冲区到底在哪里,我认为指向的第一个字节我的字符串)和文本片段的字节长度(在本例中为 .len)。我的问题是当我需要写东西的时候,这个十六进制的业务是如何工作的,mov rax 指令的实际工作是什么。
mov rdi, 1: 我还是不明白到底发生了什么。我们需要一个 1 来将输出设置为 stdout,但是这条指令的实际功能是什么,这个 1 去哪儿了,幕后发生了什么。
然后我们有这个str.len我不太明白,这个.len符号是什么?我知道这给出了字符串的大小,但是我们怎么写呢像这样?
系统调用:这个函数看起来像黑魔法,我知道 Os 在做一些卑鄙的把戏,但我对 OS 很无知,所以我看不懂这个东西在做什么。
mov rax, 0x2000001: 现在我们需要退出程序,为什么我们需要将这个十六进制数加载到寄存器中(是的,我知道这是退出的命令,但又是什么实际上正在发生)。
xor rdi, rdi:这可能是我得到的唯一位,我们通过异或相同的两个值将 rdi 寄存器的内容设置为 0。
系统调用:这是黑魔法
str:“Hello World”:我明白了 :)
.len: 我不明白这个.notation。我认为 $ 的意思是“这里的地址”或者至少这是我查过的东西,我认为它是正确的。
- 不,那只是导出符号。
- 不,它告诉汇编程序将以下内容放入哪个部分。
.text
是代码的默认部分。
- 不,那是一个标签。函数入口点通常由标签表示,但并非所有标签都是函数。
- 在 MacOS 上,值
0x2000004
是指定您想要 write
系统调用的代码。 OS 将查找 rax
以确定调用者想要什么。所有系统服务都有一个代码。你可以想象 OS 做类似 if (rax == 0x2000004) do_write(rdi, rsi, rdx);
的事情
rdi
是一个寄存器。你知道寄存器,对吧?与上面的第 4 点类似,OS 一旦确定您想要 write
将检查 rdi
以获取目标文件描述符。
str.len
只是一种标签语法。该值在底部定义。不过,这应该加载到 rdx
而不是 rdi
。
- 它将控制转移到 OS。然后查看寄存器的内容并执行请求的操作。 OS 只是代码,尽管有特权。
至于(12),是的,$
是当前位置,也就是字符串的结尾。所以减去字符串的开头会给你长度。前导点只是一个特殊标签,它指示汇编器在其前面加上最近的前一个非本地标签,在本例中为 str
。所以这相当于写 str.len
.
我在为 mac os(x86_64 体系结构)进行汇编时遇到了很多困难。我想向您介绍一个 hello world 程序的解释,如果您能给我您的反馈以及建议和解释,我将不胜感激:话虽如此,让我们进入代码。
你好世界程序
以前从未感受过Hello world的痛苦。 所以,这是我从互联网上复制粘贴的代码:global _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
mov rsi, str
mov rdi str.len
syscall
mov rax, 0x2000001
xor rdi, rdi
syscall
section .data
str: “Hello world”,
.len: equ $ - str
所以让我为难自己:
global _main 基本上告诉链接器从哪里开始,如果我没记错的话
.text 部分告诉 OS(我猜)这是实际程序的开始。
_main 如果我没记错的话是一个函数,这似乎是函数的表示法
mov rax, 0x2000004 : 我不明白这个东西是做什么的。我在网上查了一下系统调用是如何工作的,它基本上需要一个文件代码(我认为这是下一行的 1),一个指向缓冲区的指针(这个缓冲区到底在哪里,我认为指向的第一个字节我的字符串)和文本片段的字节长度(在本例中为 .len)。我的问题是当我需要写东西的时候,这个十六进制的业务是如何工作的,mov rax 指令的实际工作是什么。
mov rdi, 1: 我还是不明白到底发生了什么。我们需要一个 1 来将输出设置为 stdout,但是这条指令的实际功能是什么,这个 1 去哪儿了,幕后发生了什么。
然后我们有这个str.len我不太明白,这个.len符号是什么?我知道这给出了字符串的大小,但是我们怎么写呢像这样?
系统调用:这个函数看起来像黑魔法,我知道 Os 在做一些卑鄙的把戏,但我对 OS 很无知,所以我看不懂这个东西在做什么。
mov rax, 0x2000001: 现在我们需要退出程序,为什么我们需要将这个十六进制数加载到寄存器中(是的,我知道这是退出的命令,但又是什么实际上正在发生)。
xor rdi, rdi:这可能是我得到的唯一位,我们通过异或相同的两个值将 rdi 寄存器的内容设置为 0。
系统调用:这是黑魔法
str:“Hello World”:我明白了 :)
.len: 我不明白这个.notation。我认为 $ 的意思是“这里的地址”或者至少这是我查过的东西,我认为它是正确的。
- 不,那只是导出符号。
- 不,它告诉汇编程序将以下内容放入哪个部分。
.text
是代码的默认部分。 - 不,那是一个标签。函数入口点通常由标签表示,但并非所有标签都是函数。
- 在 MacOS 上,值
0x2000004
是指定您想要write
系统调用的代码。 OS 将查找rax
以确定调用者想要什么。所有系统服务都有一个代码。你可以想象 OS 做类似if (rax == 0x2000004) do_write(rdi, rsi, rdx);
的事情
rdi
是一个寄存器。你知道寄存器,对吧?与上面的第 4 点类似,OS 一旦确定您想要write
将检查rdi
以获取目标文件描述符。str.len
只是一种标签语法。该值在底部定义。不过,这应该加载到rdx
而不是rdi
。- 它将控制转移到 OS。然后查看寄存器的内容并执行请求的操作。 OS 只是代码,尽管有特权。
至于(12),是的,$
是当前位置,也就是字符串的结尾。所以减去字符串的开头会给你长度。前导点只是一个特殊标签,它指示汇编器在其前面加上最近的前一个非本地标签,在本例中为 str
。所以这相当于写 str.len
.