7

アセンブリの学習を開始すると、Linux のクラスで作成された Hello World アセンブリ コードが与えられました。64 ビットの Mac OS X で動作するようにしたいと考えています。

コード.asm :

SECTION .data       
    hola:   db "Hola!",10   
    tam:    equ $-hola      

SECTION .text       
    global main     

main:               

    mov edx,tam     
    mov ecx,hola        
    mov ebx,1       
    mov eax,4       
    int 0x80        

    mov ebx,0       
    mov eax,1       
    int 0x80        

これが私がすることです:

nasm -f macho32 -o object.o code.asm
gcc -m32 -o program object.o

それは私に言います:

アーキテクチャ i386 の未定義シンボル: "_main"、参照元: crt1.10.6.o ld で開始: アーキテクチャ i386 のシンボルが見つかりません

このエラーを検索すると、次の質問が見つかりました: nasm and gcc: 32 bit linking failed (64 bit Mac OS X)

1つの答えは言う

あなたが抱えている問題は、Mac OS X オブジェクト形式と互換性のない 32 ビット Linux(ELF) オブジェクト ファイルを作成していることです。「-f elf」を「-f macho32」に切り替えてみてください。

しかし、私は間違いなく使用して-f macho32います。では、何が問題になるのでしょうか?

4

2 に答える 2

8

私も入門レベルのアセンブリ プログラミングを独学で学ぼうとしてきましたが、同様の問題に遭遇しました。nasmもともとwithを使用してコンパイルしていましたが、 を使用してオブジェクト ファイルをリンクし、実行可能ファイルを作成elfしようとしたときに機能しませんでした。ld

主な質問の答え"what would the problem be then?" [to get this to run on 64bit MacOSX]は次のとおりだと思います。使用-f macho32していますが、64ビットマシンで実行することを期待しています。コマンドオプションをに変更する必要があります-f macho64もちろん、これはアセンブリ コードが別のアーキテクチャ用に記述されているという事実を解決するものではありません (これについては後で説明します)。

このインスタンスでコードをコンパイルおよびリンクするために使用する適切なコマンドで、この便利な回答を見つけました (アセンブリ コードをリファクタリングして、*nix の代わりに適切な構文を使用するようにした後、duskwuffが述べたように):nasm -f macho64 main.asm -o main.o && ld -e _main -macosx_version_min 10.8 -arch x86_64 main.o -lSystem

いくつかの検索の後、これが私が学んだことです...

  1. Mac 64 ビットでは、 (よりネイティブなものが必要な場合)as代わりにアセンブラーを使用する方が良いかもしれませんが、よりポータブルなコードが必要な場合 (違いを学んでください)。nasm
  2. nasmデフォルトでインストールされている macho64 出力タイプは付属していません
  3. 組み立てはキースターの面倒(これはさておき)

私の学習暴言が邪魔にならないようになったので...

以下を使用して MacOSX 64 で動作するコードを次に示します(で更新したnasm場合は、 Dustin Schultzの功績によるものです):nasmmacho64

section .data
hello_world     db      "Hello World!", 0x0a

section .text
global start

start:
mov rax, 0x2000004      ; System call write = 4
mov rdi, 1              ; Write to standard out = 1
mov rsi, hello_world    ; The address of hello_world string
mov rdx, 14             ; The size to write
syscall                 ; Invoke the kernel
mov rax, 0x2000001      ; System call number for exit = 1
mov rdi, 0              ; Exit success = 0
syscall                 ; Invoke the kernel

asMacOSX64 ネイティブのアセンブラーで使用した作業コード:

.section __TEXT,__text

.global start

start:
  movl $0x2000004, %eax           # Preparing syscall 4
  movl $1, %edi                   # stdout file descriptor = 1
  movq str@GOTPCREL(%rip), %rsi   # The string to print
  movq $100, %rdx                 # The size of the value to print
  syscall

  movl $0, %ebx
  movl $0x2000001, %eax           # exit 0
  syscall

.section __DATA,__data
str:
  .asciz "Hello World!\n"

コンパイル コマンド:as -arch x86_64 -o hello_as_64.o hello_as_64.asm

リンク コマンド:ld -o hello_as_64 hello_as_64.o

コマンドを実行:./hello_as_64

旅の途中で見つけた役立つリソース:

ASOSX アセンブラー リファレンス: https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/Assembler/Assembler.pdf

Mac OSX での 64 ビット アセンブリの書き込み: http://www.idryman.org/blog/2014/12/02/writing-64-bit-assembly-on-mac-os-x/

を使用してオブジェクト ファイルをリンクできませんでしたld: ld を使用してオブジェクト ファイルをリンクできません - Mac OS X

OSX i386 SysCall : http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/mach/i386/syscall_sw.h

OSX マスター システム コールの定義: http://www.opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master

OSX Syscall : https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/syscall.2.html

于 2015-11-08T01:07:44.817 に答える