Compile intel assembly with gcc/mingw - gcc

I want to compile intel syntax assembly using gcc. Is it possible? because I cant find something similar. I've only found this post.
Here is the code I am trying to compile.
global _main
section .text
_main:
mov eax, -1
ret
If this is not possible please provide alternative options in your answer.

Adding a .intel_syntax directive works for me:
.globl _main
.intel_syntax
_main:
mov eax, -1
ret
Assembling and running:
$ gcc -o example example.s; ./example; echo $?
255

Related

Error "16434 illegal hardware instruction ./a.out" when running x86 executable

I'm learning the basics of x86 via this free book.
Keep in mind this is specific to macOS x86 compared to Linux x86.
Its made for GNU Linux, so I have to change some of the code which is probably where I went wrong. I took this code snippet:
.section .data
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80
After a bit of googling about x86 on macOS I turned that bit of code into this:
.data
.text
.globl _main
_main:
movl $1, %eax
movl $0, %ebx
int $0x80
I compiled this using gcc test.s which compiles it into a.out. When trying to run it using ./a.out I get the error [1] 17301 illegal hardware instruction ./a.out.
Any help is appreciated, thanks!
#Jester helped me out. You can view the comment on my question, but basically call convention is different for macOS. I found this resource which helped me out.

Nasm Dwarf Error Bad Offset

I have a simple Hello World program for Windows in pure x86 assembly code that I have compiled and linked with nasm and ld. The problem I am running into is that I can't get DWARF debugging to work. I am using gdb from Mingw64 (i686-posix-dwarf-rev1). This same problem happens if I use gcc to link instead of ld. But, the program builds fine, and if I use STABS debugging, then everything is fine and dandy.
EDIT: Oops, I completely forgot to give the error that gdb shows.
...Dwarf Error: bad offset (0x407000) in compilation unit header (offset 0x0
+ 6) [in module C:\Projects\AsmProjects\HelloWorldWin32\bin\x86\hello32.exe]
(no debugging symbols found)...done
The versions of each program are:
gdb 7.10.1
nasm 2.12.02
ld 2.25
gcc 6.2.0
These are the flags I'm sending to nasm: -f elf32 -Fdwarf -g
These are the flags for gcc link: -o $(BDIR)/x86/$#.exe $^ -L$(Mingw64-x86libs) -lkernel32 -luser32
And these are from ld link:
-mi386pe -o $(BDIR)/x86/$#.exe $^ -L$(Mingw64-x86libs) -lkernel32 -luser32
I have a pretty big makefile, so I'm trying to give the least information that is absolutely neccessary.
Here is the source code for the program:
global _main
extern _GetStdHandle#4
extern _WriteFile#20
extern _ExitProcess#4
section .text
_main:
push ebp
mov ebp,esp
; GetstdHandle( STD_OUTPUT_HANDLE)
push -11
call _GetStdHandle#4
mov ebx, eax
; WriteFile( hstdOut, message, length(message), &bytes, 0);
push 0
push esp
push message_end
push message
push ebx
call _WriteFile#20
; ExitProcess(0)
push 0
call _ExitProcess#4
section .data
message db 'Hello, World',10
message_end equ $ - message
This is not a proper answer but was too long for the comment section.
I compiled on Ubuntu and then ran dwarfdump
It gave an error that may be related to the offset error.
dwarfdump ERROR: dwarf_get_globals: DW_DLE_PUBNAMES_VERSION_ERROR (123)
From a similar error on LLVM, I conclude that the dwarf version information is possibly corrupt or unsupported.
This post indicates that the dwarf information is sensitive to the proper section names. The example appears to have the section names right however.
Have you tried a 64-bit version? Perhaps a clue will appear.
This program appears to work fine Ubuntu. Can you try it on Mingw64?
section .text
global _start ;must be declared for linker (ld)
_start: ;tell linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string

PIE disabled. Absolute addressing when asm programming with gcc on mac OS X

I wrote the code below. I want to compile it using gcc on mac OS X,
but I get a message saying "PIE disabled. Absolute addressing" when I run gcc.
I googled it, but cannot find a solution.
Please advise.
hello.s file:
.data
hello: .string "Hello World!\n"
.text
.globl _main
_main:
push %rbp
mov %rsp, %rbp
movabs $hello, %rdi
call _printf
leave
ret
The error:
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in
code signed PIE, but used in _main from /var/folders/xs/4z9kr_n93111fhv9_j1dd9gw0000gn/T/ex2_64-369300.o.
To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
Looks like there are a couple solutions:
Link with -Wl,-no_pie:
clang -o hello hello.s -Wl,-no_pie
Don't use absolute addressing.
.data
hello: .string "Hello World!\n"
.text
.globl _main
_main:
push %rbp
mov %rsp, %rbp
lea hello(%rip), %rdi
mov $0, %rax
call _printf
leave
ret
Then you can compile and run:
host % clang -o hello hello.s
host % ./hello
Hello World!
The bit about zeroing out al is mentioned in section 3.5.7 of System V Application Binary Interface. Here's the relevant excerpt:
When a function taking variable-arguments is called, %al must be set
to the total num- ber of floating point parameters passed to the
function in vector registers.
In your case this is zero. You are passing in zero floating point parameters.

Why am I getting a warning about absolute addressing with immediate operands?

This little program works fine on OS X, using nasm:
global _main
extern _puts
section .text
default rel
_main:
push rbp
lea rdi, [message]
call _puts
pop rbp
ret
message:
db 'Hello, world', 0
Here's how it runs:
$ nasm -fmacho64 hello.asm && gcc hello.o && ./a.out
Hello, world
But if I replace the LEA instruction (with a memory operand) with an equivalent MOV immediate:
global _main
extern _puts
section .text
default rel
_main:
push rbp
mov rdi, message ; <---- Should have same effect as lea rdi, [message]
call _puts
pop rbp
ret
message:
db 'Hello, world', 0
The program will run but with a warning message, that I know has been asked about before on Stack Overflow:
$ nasm -fmacho64 hello.asm && gcc hello.o && ./a.out
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from hello.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
Hello, world
My question is why does this warning occur? I see the error is complaining about the linker not liking absolute addressing; however the MOV command is clearly using an immediate operand, not an absolute address! Is the warning mislabeled? I'm puzzled that
As an aside, this distinction does not happen under Linux. Removing default rel and the underscores on main and puts gives me a warning-free run on Ubuntu. What is OS X doing differently here? Is it a case of the assembler default configurations being set differently? Or is it something weird like OS X following AMD's ABI more closely than Ubuntu?

Hello world using nasm in windows assembly

I'm using nasm to compile the following assembly. However the code crashes in the console under Windows.
C:\>nasm -f win32 test.asm -o test.o
C:\>ld test.o -o test.exe
section .data
msg db 'Hello world!', 0AH
len equ $-msg
section .text
global _WinMain#16
_WinMain#16:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 80h
mov ebx, 0
mov eax, 1
int 80h
According to this post. The main function is not available under Windows and must be replaced by WinMain.
So if your entry point is _start or main, it should be changed to _WinMain#16 and change the ret at the end of the procedure to ret 16:
My working example:
section .text
global _WinMain#16
_WinMain#16:
mov eax, 0
ret 16
The biggest problem is that you are trying to use Linux interupts on windows!
int 80 will NOT work on windows.
We are using Assembly, so your entry point can be ANY label you want. The standard entry point that ld looks for is _start, if you want to use another label, you need to tell ld with the -e option
So if you want your start label to be main, then you need
global main
ld -e main test.o -o test.exe
If you are going to use NASM on Windows, I will recommend using GoLink as your linker.
Here is a simple windows console app:
STD_OUTPUT_HANDLE equ -11
NULL equ 0
global GobleyGook
extern ExitProcess, GetStdHandle, WriteConsoleA
section .data
msg db "Hello World!", 13, 10, 0
msg.len equ $ - msg
section .bss
dummy resd 1
section .text
GobleyGook:
push STD_OUTPUT_HANDLE
call GetStdHandle
push NULL
push dummy
push msg.len
push msg
push eax
call WriteConsoleA
push NULL
call ExitProcess
makefile:
hello: hello.obj
GoLink.exe /console /entry GobleyGook hello.obj kernel32.dll
hello.obj: hello.asm
nasm -f win32 hello.asm -o hello.obj
Although, this same program probably will run in WINE on Linux like a charm. :)
WINE doesn't prevent using Linux system calls from inside Windows PE binaries; the machine instructions run natively and WINE only provides DLL functions.

Resources