我正在尝试学习一些汇编程序,因此我一直遵循the most basic tutorial I can find,其中考虑了macOS和基于Linux的操作系统之间的差异。我正在运行macOS Catalina 10.15.1。
很遗憾,我无法链接示例。跟随this answer,我可以通过将hello.asm
标志添加到-lSystem
来链接基本的ld
,即我将以下代码另存为hello.asm
:
; ---------------------------------------------------------------------------------------- ; Writes "Hello, World" to the console using only system calls. Runs on 64-bit macOS only. ; To assemble and run: ; ; nasm -fmacho64 hello.asm && ld hello.o && ./a.out ; ---------------------------------------------------------------------------------------- global start section .text start: mov rax, 0x02000004 ; system call for write mov rdi, 1 ; file handle 1 is stdout mov rsi, message ; address of string to output mov rdx, 13 ; number of bytes syscall ; invoke operating system to do the write mov rax, 0x02000001 ; system call for exit xor rdi, rdi ; exit code 0 syscall ; invoke operating system to exit section .data message: db "Hello, World", 10 ; note the newline at the end
并且不运行给定的链接/执行命令,而是运行
nasm -f macho64 hello.asm && ld -lSystem hello.o && ./a.out
并且它成功地链接了
Hello, World
并将其写入stdout
。
但是,当我转到第二个示例时,
; ---------------------------------------------------------------------------------------- ; This is an OSX console program that writes a little triangle of asterisks to standard ; output. Runs on macOS only. ; ; nasm -fmacho64 triangle.asm && gcc hola.o && ./a.out ; ---------------------------------------------------------------------------------------- global start section .text start: mov rdx, output ; rdx holds address of next byte to write mov r8, 1 ; initial line length mov r9, 0 ; number of stars written on line so far line: mov byte [rdx], '*' ; write single star inc rdx ; advance pointer to next cell to write inc r9 ; "count" number so far on line cmp r9, r8 ; did we reach the number of stars for this line? jne line ; not yet, keep writing on this line lineDone: mov byte [rdx], 10 ; write a new line char inc rdx ; and move pointer to where next char goes inc r8 ; next line will be one char longer mov r9, 0 ; reset count of stars written on this line cmp r8, maxlines ; wait, did we already finish the last line? jng line ; if not, begin writing this line done: mov rax, 0x02000004 ; system call for write mov rdi, 1 ; file handle 1 is stdout mov rsi, output ; address of string to output mov rdx, dataSize ; number of bytes syscall ; invoke operating system to do the write mov rax, 0x02000001 ; system call for exit xor rdi, rdi ; exit code 0 syscall ; invoke operating system to exit section .bss maxlines equ 8 dataSize equ 44 output: resb dataSize
我从ld得到一个错误。 (请注意给出的bash命令中的错字。我实际上尝试过
nasm -f macho64 triangle.asm && ld -lSystem triangle.o && ./a.out
。)消息是:
Undefined symbols for architecture x86_64: "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture x86_64
这与我链接不带
-lSystem
标志的第一个示例时的错误相同;但是,在此处添加-lSystem
标志并不能解决问题。
在最高演唱会级别,我必须对triangle.asm
进行什么修订,或者我要使用链接对其进行链接的命令来解决此“未定义符号”错误?从更一般的层面上讲,为什么我会收到这个错误?符号_main
在我的代码中没有出现。我的目标文件是否真的被链接器“包装”在其他东西中以创建可运行的可执行文件?如果是这样,这是否是必需的默认值?为什么处理器不能仅从上至下有效地运行这些指令?我以为该代码是足够低级的,因此可以在不链接任何其他库的情况下运行。
我正在尝试学习一些汇编程序,因此我一直在遵循最基本的教程,我发现该教程考虑了macOS和基于Linux的操作系统之间的差异。我正在运行macOS ...
已经在macOS 10.15中进行了测试。%nasm -f macho64 -o tri.o triangle.asm%ld -o tri -e start tri.o -macosx_version_min 10.15-静态%./三输出:enter image description here