macOS assembly, cannot use str() command [duplicate] - macos

This question already has answers here:
What is the meaning of MOV (%r11,%r12,1), %edx?
(2 answers)
How is $example different from example(%rip)?
(1 answer)
Closed 4 years ago.
I have been following this tutorial and have got stuck at the following code: leaq str(%rip), %rdi.
My full assembly code is the following:
.data
.text
.globl _main
_main:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
leaq str(%rip), %rdi
callq _printf
And my Makefile:
build:
as main.s -o main.o
ld main.o -e _main -lc -macosx_version_min 10.13 -arch x86_64 -o main
run: build
./main
And finally the output of the command make build:
as main.s -o main.o
ld main.o -e _main -lc -macosx_version_min 10.13 -arch x86_64 -o main
Undefined symbols for architecture x86_64:
"str", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
make: *** [build] Error 1
How am I able to link the str command for use in macOS assembly?

Related

How do I compile assembly?

The problem is that I have a filesystem in documents/assembly that goes like this:
test.s:
.global _start
.text
_start:
mov $60, %rax # exit
mov $0, %rdi # return code 0
syscall
test.o:
\* exists \*
compile.bash:
as -o test.o test.s && ld -e _start -o test.s test.o && chmod 777 test.o && (./test ; echo $?)
But when I try running compile.bash I get:
ld: dynamic executables or dylibs must link with libSystem.dylib for architecture x86_64
And when I try running test.o:
bash: ./test.o: cannot execute binary file
I'm using gnu assembler, But instead of gcc in the tutorial I say as.
I tried changing the command, But what happened was that it gave a lot of errors. I'm using macos monetary version 12.5.1 (21G83). What I expected was it to print 0 when running the command, But it didn't.

nasm and ld: xxx not specified for Mac OS Ventura

I tried to assemble a Hello World but ld is throwing me a couple of errors.
Hello World:
section .data
msg db "Hello world",10
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, 13
syscall
mov rax, 60
mov rdi, 0
syscall
nasm & ld:
nasm -f elf64 main.asm
ld main.o -o main
ld gives me these errors:
ld: warning: platform not specified
ld: warning: -arch not specified
ld: warning: No platform min-version specified on command line
ld: warning: ignoring file main.o, building for -unknown but attempting to link with file built for unknown-unsupported file format ( 0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 )
Undefined symbols for architecture unknown:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture unknown
I tried using nasm with macho64
nasm -f macho64 main.asm
and got the following errors from ld:
ld: warning: alignment (1) of atom '_start' is too small and may result in unaligned pointers
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
Thanks in advance

Segmentation fault call printf NASM

I'm using a Macbook pro with Yosemite. Can't get the printf to work. Here's my code:
extern _printf
global _main
section .data
msg: db "Hello World"
section .text
_main:
push msg
call _printf
add esp, 4
ret
Using:
nasm -f macho test.s && gcc -arch i386 -e _main test.o && ./a.out
Output:
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from test.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
Segmentation fault: 11
I'd really appreciate any help.
This answered my question perfectly! How to print argv[0] in NASM?

NASM Hello World either segfaults or bus errors in Mac OS X

I'm writing Hello World in NASM, and I can get it to echo Hello World to the console, but the program segfaults if I don't run it with Make.
Trace with Makefile:
$ make
nasm -f macho -o hello.o --prefix _ hello.asm
ld -o hello hello.o -arch i386 -lc -macosx_version_min 10.6 -e _start -no_pie
./hello
Hello World!
Trace with manual commands:
$ nasm -f macho -o hello.o --prefix _ hello.asm
$ ld -o hello hello.o -arch i386 -lc -macosx_version_min 10.6 -e _start -no_pie
$ ./hello
Segmentation fault: 11
hello.asm:
[bits 32]
section .data
msg: db "Hello World!", 0
section .text
global start
extern puts
extern exit
start:
push msg
call puts
add esp, 4
push 0
call exit
Makefile:
# Linux defaults
FORMAT=-f elf
MINV=
ARCH=-arch i386
LIBS=
RUN=./
EXECUTABLE=hello
PREFIX=
ENTRY=
PIE=
# Windows
ifeq (${MSYSTEM},MINGW32)
FORMAT=-f win32
EXECUTABLE=hello.exe
PREFIX=--prefix _
ENTRY=-e _start
ARCH=
LIBS=c:/strawberry/c/i686-w64-mingw32/lib/crt2.o -Lc:/strawberry/c/i686-w64-mingw32/lib -lmingw32 -lmingwex -lmsvcrt -lkernel32
ENTRY=
RUN=
endif
# Mac OS X
ifeq ($(shell uname -s),Darwin)
FORMAT=-f macho
PREFIX=--prefix _
ENTRY=-e _start
LIBS=-lc
MINV=-macosx_version_min 10.6
PIE=-no_pie
endif
all: test
test: $(EXECUTABLE)
$(RUN)$(EXECUTABLE)
$(EXECUTABLE): hello.o
ld -o $(EXECUTABLE) hello.o $(ARCH) $(LIBS) $(MINV) $(ENTRY) $(PIE)
hello.o: hello.asm
nasm $(FORMAT) -o hello.o $(PREFIX) hello.asm
clean:
-rm $(EXECUTABLE)
-rm hello.o
Specs:
ld 64-134.9
LLVM 3.1svn
NASM 0.98.40
Make 3.81
Xcode 4.5
Mac OS X 10.8.1
MacBook Pro 2009
2 things, your hello world string is not NULL terminated and as I mentioned in another post, when you use C functions, you MUST adjust esp after each call
You tore down your stack frame twice:
mov esp, ebp
pop ebp
...
leave
You only need one of those, since leave is equivalent to mov esp, ebp; pop ebp.
See http://michaux.ca/articles/assembly-hello-world-for-os-x for several example hello world programs. Note that all of them exit the program explicitly with
; 2a prepare the argument for the sys call to exit
push dword 0 ; exit status returned to the operating system
; 2b make the call to sys call to exit
mov eax, 0x1 ; system call number for exit
sub esp, 4 ; OS X (and BSD) system calls needs "extra space" on stack
int 0x80 ; make the system call
because you cannot ret from an entry point (there's nothing to return to).
Also note that if you call the function main and don't supply the e option to ld, then libc's entry point will be called. In that case, it is permissible to ret since you will return control to libc (which calls exit on your behalf).

link nasm program for mac os x

i have some problems with linking nasm program for macos:
GLOBAL _start
SEGMENT .text
_start:
mov ax, 5
mov bx, ax
mov [a], ebx
SEGMENT .data
a DW 0
t2 DW 0
fry$ nasm -f elf test.asm
fry$ ld -o test test.o -arch i386
ld: warning: in test.o, file was built for unsupported file format which is not the architecture being linked (i386)
ld: could not find entry point "start" (perhaps missing crt1.
fry$ nasm -f macho test.asm
fry$ ld -o test test.o -arch i386
ld: could not find entry point "start" (perhaps missing crt1.o)
can anyone help me?
The Mac OS X linker can't link ELF objects. It works only with the Mach-O executable format. Unless you want to figure out how to translate the object files, you'll probably be better off writing code that works with the Mac OS X assembler.
Edit: As #Fry mentions in the comment below, you can make nasm put out Mach-O objects. In that case, the problem is simple - take the _ off of _start in both places in your source file. The result links fine.
nasm -f macho test.asm
ld -e _start -o test test.o
For people who need to stick with the elf format and develop on a mac, you need a cross compiler...
http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux
Then you can proceed with something similar to this...
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o

Resources