How do I link .obj assembler file correctly? [duplicate] - windows

This question already has answers here:
How to write hello world in assembly under Windows?
(9 answers)
System Calls in Windows & Native API?
(5 answers)
Closed 5 days ago.
I want to check, that my assembler code works and copy "hello world" program. It compiles and links succesfully, but it doesn't have output. I use NASM, WinGW64
a.asm code
global _start
section .text
_start:
mov rax, 1 ; write(
mov rdi, 1 ; STDOUT_FILENO,
mov rsi, msg ; "Hello, world!\n",
mov rdx, msglen ; sizeof("Hello, world!\n")
syscall ; );
mov rax, 60 ; exit(
mov rdi, 0 ; EXIT_SUCCESS
syscall ; );
section .rodata
msg: db "Hello, world!", 10
msglen: equ $ - msg
compile using cmd command: "nasm -f win64 a.asm"
link with "ld a.obj"
run and no output in cmd

Related

Assembly read user input doesn't wait

I have a assembly program which should write "What's your name?", then wait for user input, and then print "Hello, ". This is my program(Mac, nasm):
section .data
question db "What's your name?"
answer db "Hello, "
ln db 10
section .bss
name resb 16
section .text
global start
start:
mov rsi, question
mov rdi, 17
call print
call getName
mov rsi, answer
mov rdi, 7
call print
mov rsi, ln
mov rdi, 1
call print
mov rax, 0x02000001
mov rdi, 0
syscall
print:
mov rax, 0x02000004
mov rdi, 1
syscall
ret
getName:
mov rax, 0x02000003
mov rdi, 0
mov rsi, name
mov rdx, 16
syscall
ret
But this program writes "What's your name?Hello," and only then awaits for user input.
Why doesn't it wait for the input before it writes "Hello,"?
I mixed up rdx and rdi in start and forgot to print out the name. My bad.
EDIT: For some reason I cannot accept this answer, so: This it the accepted answer!
Your code is totally wrong. Register RAX must the value of service syscall. I will help you to correct the code for full program.
compile it with:
nasm -f elf64 -o objname.o sourcecode.asm
ld -m elf_x86_64 -o execname objname.o
%macro print 2
mov rax,1
mov rdi,rax
mov rsi,%1
mov rdx,%2
syscall
%endmacro
%macro getinput 2
mov rax,0
mov rdi,rax
mov rsi,%1
mov rdx,%2
syscall
%endmacro
%macro exit 0
mov rax,60
xor rdi,rdi
syscall
%endmacro
section .data
question db "What's your name?"
lenques equ $-question
answer db "Hello, "
lenans equ $-answer
ln db 10
lenname equ 30
section .bss
name resb lenname
section .text
global _start
_start:
print question,lenques
push rax
getinput name,lenname
print answer,lenans
pop rbx
print name,rbx
print ln,1
exit

Segfault on NASM Hello World Mac OSX 64 bit

I'm trying to learn NASM. I compile and run the file but it segfaults. The (64 bit) code follows:
global _main
section .text
_main:
mov rax, 0x2000004 ; write
mov rdi, 1 ; stdout
mov rsi, msg
mov rdx, msg.len
syscall
mov rax, 0x2000001 ; exit
mov rdi, 0
syscall
section .data
msg: db "Hello, world!", 10
.len: equ $ - msg
I compile and link it as:
nasm -f macho64 hello.asm
ld hello.o -e _main -o hello -macosx_version_min 10.7

Moving contents from .data section to register in NASM [duplicate]

This question already has an answer here:
NASM issue on OSX 64-bit [duplicate]
(1 answer)
Closed 4 years ago.
I'm new to NASM and have struggle moving contents of variable from .data section to register. Following code outputs "Value: 0" instead of "Value: 1". If I write constant to register directly (mov qword rax, 25) everything works OK.
; /usr/local/bin/nasm -f macho64 sum.asm && ld -macosx_version_min 10.7.0 -lSystem -o sum sum.o && ./sum
section .data
myvar: dq 1234
message: db "Value: %i", 10, 0
.len: equ $ - message
global start
extern _printf
extern _exit
section .text
start:
default rel
; This outputs "Value: 0"
mov qword [myvar], 1
mov rax, [myvar]
; This works:
; mov qword rax, 25
; Output
mov rsi, rax
mov qword rax, 0
lea rdi, [rel message]
call _printf
mov qword rax, 0
call _exit
/usr/local/bin/nasm -v says:
NASM version 2.11.08 compiled on Mar 10 2015
The OS X NASM 2.11.08 bug strikes again. Use an older version (like 2.11.06), or a newer version with a fix for relative symbol addressing in the data section. Or use yasm.
Like I said in comments, you can zero a 64bit register with xor eax, eax. That's the standard idiom.
Writing to a 32bit reg always clears the upper32 of the 64bit register. This saves a lot of instruction bytes compared to moving a 64bit immediate.
mov qword rax, 25
Is still a 32bit immediate move. The qword is unnecessary. The instruction does have an unneeded REX prefix to make it a 64bit write, instead of just automatically clearing the high 32 by writing the low 32.
mov eax, 25
does the same thing, but with fewer instruction bytes.
Your code is correct, except for the global entry point main which is needed (but not required, you can adjust the entry point -- with link options). Here you are linking with the libc printf and exit functions. While compilers differ, using printf rather than _printf can help.
With only those semantic changes (and compiling on Linux instead of Mac), your code gives the desired output:
section .data
myvar: dq 1234
message: db "Value: %i", 10, 0
.len: equ $ - message
global main
extern printf
extern exit
section .text
main:
default rel
; This outputs "Value: 0"
mov qword [myvar], 1
mov rax, [myvar]
; Output
mov rsi, rax
mov qword rax, 0
lea rdi, [rel message]
call printf
mov qword rax, 0
call exit
Compile
$ nasm -felf64 -o obj/label64.o label64.asm
$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o \
/usr/lib64/crti.o obj/label64.o /usr/lib64/crtn.o -lc -o bin/label64
Output
$ ./bin/label64
Value: 1
Note: you may need to adjust the paths needed by the link command. Otherwise, you can just call gcc and let it sort the paths out. E.g.:
$ gcc -o bin/label64 obj/label64.o

NASM 'fatal: No section for index 2 offset 0 found' on Mac OS X Yosemite

This is my first time programming in assembly for the Mac, and keep getting some strange errors that I haven't had much luck with googling-wise. So far, I'm just trying to print "Hello, World!" onto the terminal. Here is my code:
global _main
section .text
_main:
mov rax, 0x20000004
mov rdi, 1
mov rsi, msg
mov rdx, msg.len
syscall
mov rax, 0x20000001
mov rdi, 0
syscall
section .data
msg: db "Hello, World!", 10
.len: equ $ - msg
Whenever I run this code, I use the command nasm -f macho64 print.asm. By the way, nasm -v prints NASM version 2.11.08 compiled on Mar 10 2015. When I use the command above, NASM gives this output:
print.asm:9: fatal: No section for index 2 offset 0 found
I'm stumped and would like any help. Thanks!
I met the seemly problem. from the:
instead of :" mov rsi, msg", use: "lea rsi, [rel msg]"

Illegal instruction: 4 (Mac 64-bit, NASM)

I'm trying to write a simple helloworld in assembler 64 on Mac with NASM.
Every time I try to run it I'm getting this error:
Illegal instruction: 4
Here is my code:
section .text
global _main
_main:
mov rax, 4
mov rbx, 1
mov rcx, tekst
mov rdx, dlugosc
int 80h
mov rax, 1
int 80h
section .data
tekst db "Hello, world", 0ah
dlugosc equ $ - tekst
I'm compiling with:
nasm -f macho64 HelloWorld.asm
And I'm linking with:
ld -o HelloWorld -arch x86_64 -macosx_version_min 10.10 -lSystem -no_pie HelloWorld.o
Any help is highly appreciated.
Let's start with the most important thing:
On Mac OSX, system calls are preceded by an 0x2000###, so for an exit it would 0x2000001.
Next, we need to use the correct registers to pass arguments.
The number of the syscall has to be passed in register rax.
rdi - used to pass 1st argument to functions
rsi - used to pass 2nd argument to functions
rdx - used to pass 3rd argument to functions
rcx - used to pass 4th argument to functions
r8 - used to pass 5th argument to functions
r9 - used to pass 6th argument to functions
A system-call is done via the syscall instruction. The kernel destroys registers rcx and r11.
So bringing this together, a fixed version of your code is:
section .text
global _main
_main:
mov rax, 0x2000004
mov rdi, 1
mov rsi, tekst
mov rdx, dlugosc
syscall
mov rax, 0x2000001
syscall
section .data
tekst db "Hello, world", 0ah
dlugosc equ $ - tekst

Resources