Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get this simple assembly to run?

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  

my attempt at executing:

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

the error

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
like image 530
user3314993 Avatar asked Dec 09 '15 23:12

user3314993


People also ask

How do I create an assembly program in Windows?

Start writing code. Begin by launching WinAsm and clicking on the File tab. Then select New Projects, and you'll see several options. Those options include Console Application and Standard EXE. If you're attempting created a GUI (graphical user interface) based application, for example, you'd select the latter. Use assembly program structure.

How to get the assembly that contains the currently executing code?

To get the assembly that contains the method that called the currently executing code, use GetCallingAssembly.

What happens if I run assembly code I don't know?

Warning: never run code you don't know. In the case of assembly it can crash your system, or worse. Assuming your assembly code is x86, And assuming it doesn't look like only rows of "01101010" or "de876f1a6bc37" And assuming that you are on Windows,

What does an assembler do?

Once you've written the code, an assembler converts it into machine code (1s and 0s). While the applications for assembly programming have grown more limited given the growing complexity of processors, Assembly remains useful for a number of purposes including writing code for stand-alone executables or device drivers. Read up on Assembly Language.


1 Answers

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

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 .

Your code would have to be changed to:

    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

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.

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 .

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.

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

like image 59
Michael Petch Avatar answered Sep 28 '22 12:09

Michael Petch