- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 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
中返回结果。主要区别如下:
ebx
、ecx
、edx
),但 OS X 在堆栈中获取参数。您以相反的顺序推送参数,然后推送额外的 4 个字节。eax
,但 OS X 将正数放入eax
。 OS X 还设置了一个条件代码,因此 jb
或 jnb
会在错误发生或未发生时跳转。BSD 系统使用名为 syscalls.master 的文件来定义系统调用。我已经链接到syscalls.master from Mac OS X 10.4.11x86 .我们可以使用它来查找每个系统调用的名称、参数和返回类型。例如:
4 PRE NONE ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); }
write(2) 系统调用是 4,所以我们用 4 加载 eax
。它有 3 个参数,所以我们以相反的顺序推送它们:我们推送缓冲区中的字节数,然后将指针推送到缓冲区,然后推送文件描述符。压入参数后,我们压入 4 个额外字节,可能使用 sub esp, 4
。然后我们执行 int 0x80
。然后我们可能想要添加 esp, 16
来删除我们推送的内容。
大多数参数和返回值都是 4 字节整数,但 OS X 中的 off_t
始终是 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
和 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(),那么我们必须 provide our own trampoline !它不同于 Linux 和其他 BSD 内核。
关于linux - 汇编 Linux 系统调用与汇编 OS x 系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33194207/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!