From owner-freebsd-questions@freebsd.org Mon Jul 31 20:36:36 2017 Return-Path: Delivered-To: freebsd-questions@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2CE06DBD26E for ; Mon, 31 Jul 2017 20:36:36 +0000 (UTC) (envelope-from freebsd@edvax.de) Received: from mailrelay12.qsc.de (mailrelay12.qsc.de [212.99.163.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.antispameurope.com", Issuer "TeleSec ServerPass DE-2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id A688267CAE for ; Mon, 31 Jul 2017 20:36:34 +0000 (UTC) (envelope-from freebsd@edvax.de) Received: from mx01.qsc.de ([213.148.129.14]) by mailrelay12.qsc.de; Mon, 31 Jul 2017 22:36:26 +0200 Received: from r56.edvax.de (port-92-195-203-176.dynamic.qsc.de [92.195.203.176]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx01.qsc.de (Postfix) with ESMTPS id 7786F3CC3F; Mon, 31 Jul 2017 22:36:25 +0200 (CEST) Received: from r56.edvax.de (localhost [127.0.0.1]) by r56.edvax.de (8.14.5/8.14.5) with SMTP id v6VKaOxC004623; Mon, 31 Jul 2017 22:36:24 +0200 (CEST) (envelope-from freebsd@edvax.de) Date: Mon, 31 Jul 2017 22:36:24 +0200 From: Polytropon To: Makketron Cc: freebsd-questions@freebsd.org Subject: Re: FreeBSD System Calls in Assembly Message-Id: <20170731223624.4f3beb90.freebsd@edvax.de> In-Reply-To: References: Reply-To: Polytropon Organization: EDVAX X-Mailer: Sylpheed 3.1.1 (GTK+ 2.24.5; i386-portbld-freebsd8.2) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-cloud-security-sender: freebsd@edvax.de X-cloud-security-recipient: freebsd-questions@freebsd.org X-cloud-security-Virusscan: CLEAN X-cloud-security-disclaimer: This E-Mail was scanned by E-Mailservice on mailrelay12.qsc.de with C13886A387C X-cloud-security-connect: mx01.qsc.de[213.148.129.14], TLS=1, IP=213.148.129.14 X-cloud-security: scantime:.1405 X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Jul 2017 20:36:36 -0000 On Mon, 31 Jul 2017 15:59:58 -0400, Makketron wrote: > Hello, > It seems that the documentation here doesn't apply for 64-bits. > > https://www.freebsd.org/doc/en/books/developers-handbook/x86.html Yes, the URL states "x86", which usually means "32 bit" (or "i386"), whereas "x86-64" indicates "64 bit" (or "amd64"). > I asked a question on stackoverflow. I thought I should ask it here too > https://stackoverflow.com/questions/45423987/freebsd-64bits-convention-call-documentation > > I am running FreeBSD 11.0. And I therefore assume you're talking about 64 bit assembly here. > global _start > _start: > push dword hbytes > push dword hello > push dword 1 ; stdout > mov rax, 4 ; write syscall > call _syscall > add rsp, byte 24 ; restore stack > push word 0 ; return 0 > mov rax, 1 ; exit call > call _syscall If I remember correctly, you need to use the registers for the parameters you want to pass to the system call. (My assembly knwoledge is quite dusty, so check the documentation!) > But this works: > > section .text > hello db 'Hello, World!, 0Ah > hbytes equ $-hello > > _syscall: > int 80h > ret > > global _start > _start: > mov rdi, 1 > mov rsi, hello ; appears to be magic > mov rdx, hbytes ; appears to be magic > mov rax, 4 ; write syscall > call _syscall > > push word 0 ; return 0 > mov rax, 1 ; exit call > call _syscall > > This raises couple questions: > > 1) Why doesn't the first approach work? The example program in "11.6. Our First Program" is a little bit different: It uses system.inc and sys.write so you don't have to manually code the syscall. https://www.freebsd.org/doc/en/books/developers-handbook/x86-first-program.html How (using which tools) do you assemble, link, and maybe brandelf? > The UNIX calling convention is push data on the stack. Program does not > crash. I just don't get any output, and the program terminates. I am > compiling and linking fine. Did you check with e. g. "truss " if the write syscall has actually been executed? And if yes, with which parameters? > 2) How are we supposed to know about what registers to load, and with what > values? You can see that from the documentation, for example regarding write, you check "man 2 write" and see: ssize_t write(int d, const void *buf, size_t nbytes); So the 1st parameter is an integer, the second a pointer, the third a size_t integer. The registers to use are... let's see if I get it right without further checking... AX is the syscall number, DI gets the destination descriptor, SI gets the address of the source buffer, DX gets the length of the buffer... I really hope this is right... I'm not sure, it could also be that you use AX, BX, CX, DX... you see I didn't do much assembly programming recently, especially not on FreeBSD. ;-) (NB: When I say "DI", I mean "edi" or "rdi" depending on architecture.) FreeBSD does support this calling convention. However, I think there is a difference between 32 bit and 64 bit. Stack-based parameter lists are possible in 32 bit, but for 64 bit, you have to use the registers. And you can use the 64 bit instruction "syscall" instead of "int 80h". > If I was pushing on the stack, it is easy. I look up the C functions and > then I know how to push data. Exactly. The order or parameters in the function prototype will tell you in which order to push the parameters on the stack. > In this case, it works like magic. It's just the right registers on 64 bit. :-) > 3) Where is the documentation for FreeBSD for similar system calls (not > utilizing stack)??! I think this is "11.3.2. Alternate Calling Convention": https://www.freebsd.org/doc/en/books/developers-handbook/x86-system-calls.html In worst case, ask on the freebsd-hackers@ mailing list. :-) -- Polytropon Magdeburg, Germany Happy FreeBSD user since 4.0 Andra moi ennepe, Mousa, ...