汇编 Linux 系统调用与汇编 OS X 系统调用

2023-12-05

我在 Mac 上运行汇编代码时遇到问题。我目前正在阅读 Jeff Duntemann 的书《Assembly Step by Step》。问题是它专注于为 32 位 Linux 系统编写汇编。我使用的是 64 位 mac os x 系统。我仍然可以使用 nasm -f macho32 在 64 位系统上运行 32 位汇编,但显然 Duntemann 书中的代码不起作用,因为 Linux 和 mac os x 中的系统调用不同。我将如何转换这个程序:

;  Executable name : EATSYSCALL
;  Version         : 1.0
;  Created date    : 1/7/2009
;  Last update     : 2/18/2009
;  Author          : Jeff Duntemann
;  Description     : A simple program in assembly for Linux, using NASM 2.05,
;    demonstrating the use of Linux INT 80H syscalls to display text.
;
;  Build using these commands:
;    nasm -f elf -g -F stabs eatsyscall.asm
;    ld -o eatsyscall eatsyscall.o
;

 SECTION .data          ; Section containing initialised data

     EatMsg: db "Eat at Joe's!",10
     EatLen: equ $-EatMsg   

 SECTION .bss           ; Section containing uninitialized data 

 SECTION .text          ; Section containing code

 global     _start          ; Linker needs this to find the entry point!

_start:
     nop            ; This no-op keeps gdb happy...
     mov eax,4      ; Specify sys_write call
     mov ebx,1      ; Specify File Descriptor 1: Standard Output
     mov ecx,EatMsg     ; Pass offset of the message
     mov edx,EatLen     ; Pass the length of the message
     int 80H            ; Make kernel call

     mov eax,1      ; Code for Exit Syscall
     mov ebx,0      ; Return a code of zero 
     int 80H            ; Make kernel call

这样它就可以在我的 mac os x 系统上运行吗?我更喜欢 32 位汇编的解决方案,因为我正在尝试学习它,而不是更复杂的 64 位汇编。

我在网上找到了一个解决方案,但它使用堆栈并有其他差异,例如从 esp 寄存器中减去,即使 Duntemann 的程序根本不引用 esp 寄存器:

global start

 section .text
 start:
    push    dword msg.len
       push    dword msg
    push    dword 1
    mov     eax, 4
    sub     esp, 4
    int     0x80
    add     esp, 16

    push    dword 0
    mov     eax, 1
    sub     esp, 12
    int     0x80

 section .data

 msg:    db      "Hello, world!", 10
.len:   equ     $ - msg

所以我想我想知道的是如何将linux系统调用转换为mac os x系统调用的逐步过程?这样,当我阅读这本书时,我就可以这样做,而不必在虚拟机或其他东西上下载 Linux。


那个解决方案是错误的。线路sub esp, 12应该sub esp, 4。它没有传递 0 作为退出状态;它传递了一个垃圾值。

Mac OS X 有 BSD 系统调用。例子很难找到,因为大多数 BSD 程序不进行直接系统调用;它们链接到 libc 并调用 libc 中包装系统调用的函数。但在汇编语言中,直接系统调用可能比 libc 调用更简单。

对于 32 位 Intel 代码,OS X 和 Linux 都会响应int 0x80。他们都将系统调用号放入eax,并且它们都返回结果eax。主要区别如下:

  • Linux 在寄存器中获取参数(ebx, ecx, edx),但 OS X 将参数放在堆栈上。您以相反的顺序压入参数,然后压入额外的 4 个字节。
  • 当发生错误时,Linux 会在其中放入一个负数eax,但 OS X 在其中输入一个正数eax。 OS X 还设置了一个条件代码,以便jb or jnb如果发生或未发生错误,则会跳转。
  • 系统调用有不同的编号,有些有不同的参数。

重要文件:系统调用.master

BSD 系统使用名为 syscalls.master 的文件来定义系统调用。我已经链接到Mac OS X 10.4.11x86 的 syscalls.master。我们可以用它来查找每个系统调用的名称、参数和返回类型。例如:

4   PRE     NONE    ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } 

write(2) 系统调用的编号为 4,因此我们加载eax4.它有3个参数,所以我们以相反的顺序推送它们:我们推送缓冲区中的字节数,然后推送指向缓冲区的指针,然后推送文件描述符。推入参数后,我们推入 4 个额外字节,也许是sub esp, 4。然后我们就做int 0x80。那么我们可能想要add esp, 16删除我们推送的内容。

大多数参数和返回值都是 4 字节整数,但是off_t在 OS X 中始终是 8 字节整数。我们必须小心像 lseek(2) 这样的调用。

199 NONE    NONE    ALL { off_t lseek(int fd, off_t offset, int whence); } 

offset 参数是一个 8 字节整数,因此我们将其作为一对 4 字节双字压入。 Intel 处理器是小端字节序,并且堆栈向下增长,因此我们在推送低位双字之前推送高位双字。 lseek(2) 的返回类型也是 off_t。它来自寄存器eax and edx,其中的低位词eax和高词在edx.

有些系统调用很奇怪。为了捕获信号,与 Linux 不同,OS X 没有对 signal(3) 的系统调用。我们必须使用 sigaction(2),但这很奇怪:

46  NONE    KERN    ALL { int sigaction(int signum, struct __sigaction *nsa, struct sigaction *osa); } 

第二个参数不是常规的 sigaction 结构。这是一个更大的结构,包括一个额外的蹦床区域。如果我们不在 libc 中调用 sigaction(),那么我们必须提供我们自己的蹦床!它与 Linux 和其他 BSD 内核不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

汇编 Linux 系统调用与汇编 OS X 系统调用 的相关文章

  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • 如何在 Mac 上使用 Process.Start() 或等效的 Mono 并传入参数

    我正在尝试编写一些 C 代码来启动浏览器Process Start app args 其中 apps 是浏览器的路径 例如 Applications Google Chrome app Contents MacOS Google Chrom
  • Linux无法删除文件

    当我找到文件时 我在删除它们时遇到问题 任务 必须找到带有空格的文件并将其删除 我的尝试 rm find L root grep i 但我有错误 rm cannot remove root test No such file or dire
  • “代码 。”无法在 OS X/Mac 上的 Visual Studio Code 命令行上工作

    命令code 不起作用本手册 https code visualstudio com docs nodejs 之前的所有其他步骤都有效 如何在 OS X 终端中调用 Visual Studio Code pwd 用户 mona nodejs
  • Python 3.4.3 subprocess.Popen 在没有管道的情况下获取命令的输出?

    我试图将命令的输出分配给变量 而不让命令认为它正在通过管道传输 原因是 如果正在通过管道传输 则相关命令会给出未格式化的文本作为输出 但如果从终端运行 则会给出颜色格式化的文本 我需要获取这种颜色格式的文本 到目前为止我已经尝试了一些事情
  • 在 docker 中重定向命令输出

    我想为我的服务器做一些简单的日志记录 它是一个在 Docker 容器中运行的小型 Flask 应用程序 这是 Dockerfile Dockerfile FROM dreen flask MAINTAINER dreen WORKDIR s
  • ssh 连接超时

    我无法在 git 中 ssh 到 github bitbucket 或 gitlab 我通常会收到以下错误消息 如何避免它 输出 ssh T email protected cdn cgi l email protection i ssh
  • vmsplice() 和 TCP

    在原来的vmsplice 执行 有人建议 http lwn net Articles 181169 如果您的用户态缓冲区是管道中可容纳的最大页面数的 2 倍 则缓冲区后半部分成功的 vmsplice 将保证内核使用缓冲区的前半部分完成 但事
  • 强制 Apache HTTPD 以 32 位运行

    我通过从二进制文件 以及 ppc 部分 中剥离 32 位架构 以 64 位模式运行 Apache HTTPD 我这样做是为了使其与 python 和 mysql 更加兼容 然而 我有另一台机器需要它以 32 位模式运行 它仍然保留所有四种原
  • 一个好的8086模拟器[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 mac 有没有 8086 模拟器 如果是 哪个是最好的 除非您需要真正的原始 8086 带有自定义操作系统 否则您应该尝试 DosBox
  • 如何将 UILabel 的值绑定到实例变量?

    我是 mac objective c 的新手 我的问题是 我想知道是否可以将 UILabel 文本绑定到变量 而不必在值更改时手动设置文本 例如 在 Mac OS 上 当我打开新的 Finder 窗口并删除文件时 任务栏中的全局可用空间就会
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • 汇编程序中的过程调用如何工作?

    我刚刚开始摆弄 ASM 我不确定我对过程调用的理解是否正确 假设代码中的某个时刻有一个过程调用 call dword ptr 123 该过程仅包含一个命令 ret ret 0004 该过程调用的效果是什么 返回值将存储在哪里 我在某处读到
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • 在 Mac 操作系统上使用 ffmpeg 录制视频

    我想在 mac OS 上使用 ffmpeg 以任何格式录制实时网络摄像头视频 我尝试了很多 但无法找到用于重新编码视频的命令 所以请任何人都可以告诉我 ffmpeg 命令用于使用 Mac 操作系统的网络摄像头捕获视频 提前致谢 对于 Mac
  • ALSA:snd_pcm_writei 调用时缓冲区不足

    当运行我最近从灰烬中带回来的旧程序时 我遇到了缓冲区不足的情况 该程序将原始声音文件完全加载到内存中 2100 字节长 525 帧 并准备 ALSA 进行输出 44 1khz 2 通道 有符号 16 位 if err snd pcm set
  • 从 64 位 nasm 代码接收 32 位寄存器

    我正在学习 64 位 nasm 我通过执行以下操作来汇编 nasm 文件 该文件仅包含 64 位寄存器 nasm f elf64 HelloWorld nasm o HelloWorld o 并链接它执行以下操作 ld HelloWorld
  • 在 mac os Sierra 上,卡在“设置 CocoaPods 主存储库”上

    转移到 mac os sierra 后 我完全格式化了我的 mac 现在每次运行时我都面临安装 cocoapods 的问题sudo gem install cocoapods pre一切都安装得很好 当我尝试安装 Pod 时 终端堆栈打开S
  • 核心数据 iCloud 同步中的关系完整性和验证

    考虑以下简单的实体模型 实体 A 与实体 B 具有一对一关系 称为b 实体 B 具有逆对一关系 称为a 这两种关系都不是可选的 A B b lt gt a 假设我们有两个设备 1 和 2 开始完全同步 每个对象都有一个 A 类对象和一个 B
  • 我可以使用 AVX FMA 单元进行位精确的 52 位整数乘法吗?

    AXV2 doesn t have any integer multiplications with sources larger than 32 bit It does offer 32 x 32 gt 32 http www felix

随机推荐