Confusion from Win32 -> Linux 64-bit assembly

Programming, for all ages and all languages.
Post Reply
mwbrown
Posts: 2
Joined: Mon Dec 17, 2007 5:53 pm

Confusion from Win32 -> Linux 64-bit assembly

Post by mwbrown »

Hello. I suppose I should introduce myself as well, considering this is my first post. I'm a hobbyist programmer (I'm going to go to college for a CE/CS degree, however), with C, C++, and Java experience. I've recently taken up Assembly as a new programming language, as a result of a newfound interest in computer engineering ;)

I started off with masm32, got a little too used to the invoke syntax, and then ended up moving to nasm after I found the license for masm32 to be incompatible with my plans. I then learned the Win32 way of calling functions, such as (this is an example of some of the libsdl bindings I worked with)

Code: Select all

push dword SDL_INIT_EVERYTHING
call SDL_Init

push dword 0
push dword 32 ; bits per pixel
push dword 480 ; resolution, x
push dword 640 ; resolution, y
call SDL_SetVideoMode
; etc etc
However, I've noticed this does not work very well on Linux 64-bit. I've tried the push/call method, and it doesn't work at all. All my calls are being executed, but I'm not sending the data in the right manner. In fact, if I try that same code on Nasm 2.00, x86_64, I end up completely freezing my window manager! (I do have SDL_Quit in there, so that's not the problem)

Also, one question about something that's been bugging me for quite a while. I've noticed that .lib files that are normally used in Microsoft programming projects are a lot better at producing small code that's easily debuggable, but the static linking that comes with using libc makes it confusing to find the entry point of an assembled binary. Is there any way to dynamically link to libc?
Learning the nuances of assembly, one "int 0x80" at a time.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

This article has always worked for me in the past.
C8H10N4O2 | #446691 | Trust the nodes.
mwbrown
Posts: 2
Joined: Mon Dec 17, 2007 5:53 pm

Post by mwbrown »

Alboin wrote:This article has always worked for me in the past.
That article mentions the method that I've used with 32-bit programming. It works just fine with the 32-bit ABI, but the 64-bit one is just confusing. For instance, if I try something like this printf test:

Code: Select all

BITS 64

extern puts
extern printf

[section .data]

szText   db 'Test print.',0
szFormat db '%s',10,0

[section .text]

global main

main:

	mov rdi, szText
	call puts ; this call works just fine

	mov rdi, szFormat
	mov rsi, szText
	call printf ; segmentation fault (null pointer somewhere?)

	mov rax, 1 ; syscall -> exit
	mov rbx, 0 ; return code = 0
	int 0x80

it segfaults when the call to printf is executed, even though the NASM manual states this on 64-bit code:
The first six integer arguments (from the left) are passed in RDI, RSI, RDX, RCX, R8, and R9, in that order. Additional integer arguments are passed on the stack. These registers, plus RAX, R10 and R11 are destroyed by function calls, and thus are available for use by the function without saving.
This has got me quite stumped, I must say. :(
Learning the nuances of assembly, one "int 0x80" at a time.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I did find this:
AMD64 ABI wrote:For calls that may call functions that use varargs or stdargs (prototype-less
calls or calls to functions containing ellipsis (. . . ) in the declaration) %al 15 is used
as hidden argument to specify the number of SSE registers used. The contents of
%al do not need to match exactly the number of registers, but must be an upper
bound on the number of SSE registers used and is in the range 0–8 inclusive.
I can't tell wether this actually solves your problem though.

If that doesn't work, your best bet is to write a function with a printf call in C, compile it and disassemble the results to see how its really done.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
binutils
Member
Member
Posts: 214
Joined: Thu Apr 05, 2007 6:07 am

Post by binutils »

User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

binutils wrote:(link to different assembler)
Using YASM will not help the OP understanding how vararg calling conventions actually work

As for yasm, it does not provide anything specific to do method invocation so it will not fix the problem either.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Go here: http://flatassembler.net/examples.php
And get "Linux AMD64 examples"
Post Reply