如何让这个简单的程序集运行? [英] How to get this simple assembly to run?

查看:20
本文介绍了如何让这个简单的程序集运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次尝试用汇编编程.我使用的是 64 位 Mac 操作系统.我也在使用 NASM.我已经四处寻找解决方案,但找不到任何适用于我的机器的东西.

This is my first ever attempt at programming with assembly. I'm using a 64 bit Mac OS. I'm also using NASM. I've done a lot of looking around for a solution, but I can't find anything that works for my machine.

谁能帮我解决这个问题?这是代码和错误,谢谢!

Can anyone help me solve this problem? Here is the code and error, thanks!

hello.asm

    global start

    section .text
start:
    mov rax, 1
    mov rdi, 1
    mov rsi, message
    mov rdx, 13
    syscall
    mov eax, 60
    xor rdi, rdi
    syscall
message:
    db "Hello, World", 10  

我的执行尝试:

nasm -f macho64 hello.asm -o hello.o
ld -arch i386 -o hello hello.o
./hello

错误

ld: warning: -macosx_version_min not specified, assuming 10.10
ld: warning: ignoring file hello.o, file was built for unsupported file format ( 0xCF 0xFA 0xED 0xFE 0x07 0x00 0x00 0x01 0x03 0x00 0x00 0x00 0x01 0x00 0x00 0x00 ) which is not the architecture being linked (i386): hello.o
Undefined symbols for architecture i386:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture i386

推荐答案

您的链接器错误的原因是您使用 NASM 创建了一个 64 位 macho 对象,但随后将 i386 定位为可执行文件.您可能想要的是 64 位可执行文件,可以通过像这样删除 -arch 来完成:

The reason for your linker error is that you created a 64-bit macho object using NASM, but then targeted i386 for the executable. What you likely were after was a 64-bit executable, which could be done by removing -arch like this:

ld -o hello hello.o

至于运行程序时的段错误,看来您可能遵循了可能为 Linux 设计的教程.OS/X 不是基于 Linux,它源自 BSD,因此系统调用不同.我们可以告诉您正在使用 Linux Syscalls,因为 syscall 1 是 sys_writesys_exit 是 rax = 60.不幸的是,这对于操作系统并不相同/X.在 64 位 OS/X 代码中,sys_exit 为 rax=0x20000001,sys_write 为 rax=0x20000004.

As for your segfault when running your program, it seems that you likely followed a tutorial that may have been designed for Linux. OS/X isn't base upon Linux, it derived from BSD so the Syscalls are different. We could tell you were using Linux Syscalls because syscall 1 is sys_write and sys_exit is rax = 60. This unfortunately isn't the same for OS/X. In 64-bit OS/X code sys_exit is rax=0x20000001 and sys_write is rax=0x20000004 .

您的代码必须更改为:

    global start

    section .data
message: db "Hello, World", 10  

    section .text
start:
    mov rax, 0x20000004
    mov rdi, 1
    mov rsi, message
    mov rdx, 13
    syscall
    mov rax, 0x20000001
    xor rdi, rdi
    syscall

您还会看到我明确声明了一个 .data 部分并将您的变量放入其中.在某些环境中,如果将数据变量放在代码中,可能会导致问题.

You'll also observe I explicitly declared a .data section and placed your variable in it. In some environments it may cause problems if data variables are placed in the code.

如果在 OS/X 上创建 32 位代码(在这种情况下您不是),系统调用会从每个代码中减去 0x20000000.所以在 32 位 OS/X 代码中 sys_exit 是 eax=0x1 而 sys_write 是 eax=0x4 .

If creating 32-bit code on OS/X (you aren't in this case) the Syscalls have 0x20000000 subtracted from each. So in 32-bit OS/X code sys_exit is eax=0x1 and sys_write is eax=0x4 .

OS/X 上所有系统调用(及其参数)的参考可以在这个 苹果信息.对于 64 位汇编代码,只需将 0x20000000 添加到图表第一列中的每个数字即可.

A reference for all the Syscalls (and their parameters) on OS/X can be found in this Apple information. Just add 0x20000000 to each number in the first column of the chart for 64-bit assembler code.

您可能希望找到有关 Syscall 的 64 位 OS/X 教程.这是一个简单的

You probably want to find a 64-bit OS/X tutorial about Syscalls. This is a simple one

这篇关于如何让这个简单的程序集运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆