Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Hi! I thought the response string was rwasa's fault :)

Question. I've just started to become interested in learning/messing around with assembly language under Linux, and fasm seems like a really attractive option - as and nasm are both tied to gcc (nasm indirectly), and fasm skips all that (and produces slightly smaller binaries too!). fasm also seems compiles itself in less than a second on my really old machine as well, and fast iteration time is one of my favorite features.

Linux-specific assembly-language documentation is kind of rare on the ground though; for fasm in particular, there's literally hens' teeth and dust bunnies. It's very possible to piece things together, but if you have absolutely no idea what you're doing it's a bit intimidating.

HeavyThing is practically a tutorial in and of itself, but I must admit my hesitancy to lean too heavily on it due to its use of GPLv3. I certainly respect the use of that license (and understand the many reasons it might be used for such a unique project), but I'm only tinkering around myself at this point so would likely want to use MIT, CC0 or similar, and would feel a bit conflicted about the predominant thing I learned from being from GPLv3.

HT is on the list for sure, but I wanted to combine it with other sources of info. You seem to be one of the few people out there actively using fasm for Linux development, so I figured it couldn't hurt to ask if you had any other high-level suggestions.



Start simple and hook fasm in with a "normal" gcc/g++ project... I wrote a page[0] ages ago on integrating C/C++ with the HeavyThing library and a good portion of that has nothing to do with my library specifically and is a great starting point to mess around with assembler on a Linux platform. The only other pointer is the "call PLT" format for calling externally linked functions from inside your fasm objects but that is the only tricky bit IMO.

https://2ton.com.au/rants_and_musings/gcc_integration.html


That makes a lot of sense.

I could combine this with viewing gcc's assembly output, as well!

Thanks :D

Edit: This page is ridiculously comprehensive. Wow.


The official fasm tar comes with a few hello world examples. One shows you how to say hello with libc, other with the kernel (then there's x86 and amd64 versions of bout).

http://chamilo2.grenet.fr/inp/courses/ENSIMAG3MM1LDB/documen... is the official spec for the amd64 calling convention (aka ABI) on unices. http://www.logix.cz/michal/devel/amd64-regs/ is a nice table showing what goes in what register (still amd64) when calling a C library or the kernel. X86 library calling convention is just putting everything on the stack, while the kernel convention.. i don't remember (int 80 and syscall in eax, but arguments..). There's a syscall table https://filippo.io/linux-syscall-table/ and i made a fasm to include https://pastebin.com/nnrMVF8u (amd64; i made from the kernel source headers, that i can't find now).

That's about all there is linux specific.


Hmm, interesting.

I've had a look at the examples that come with fasm, which are invaluable.

But I completely forgot to point out (I knew I was forgetting something!) in my previous comment that I'm actually looking for info on 32-bit assembly programming. My motivation comes from the fact that a) a lot of my systems are 32-bit (such as the ThinkPad T43 I'm using to type this), due to circumstances I cannot change; and b) because (as I discovered to my delight) a program written for i386 and statically linked (eg, by fasm's ELF writer) will run on x86_64 without 32-bit glibc/userspace/anything! This makes perfect sense, but is an absolute winner for me for the kinds of things I'm going to want to make.

So x86_64 is in the "it would be monumentally stupid not to learn it" category, and I'm looking forward to doing so, but I'd have to do some seriously inelegant wrangling (something like qemu-x86_64 + 64-bit userspace - on a 32-bit machine, lolol) to actually work with it at this point.

The syscall table you made is very similar to HeavyThing's, heh. I've actually been researching precisely that of late; you most likely generated your copy from https://github.com/torvalds/linux/blob/master/arch/x86/entry.... I of course want https://github.com/torvalds/linux/blob/master/arch/x86/entry....


amd64 is just an extension on x86. I took the (64bit) syscalls from a kernel header, that i can't find now, so you can take from that header you found.

C calling convention for x86 is to push everything on the stack (and use call, that is short for "push instruction pointer and jmp", ret being the reverse), while the linux kernel uses a variant of fastcall (aka put stuff in registers (then use int 80)).

When i was learning i found a lot of x86 examples and tutorials (and a book, can't remember the name (is free)), and not much on amd64.

Just play with it, it'l get easy when you go over the wall.

With "normal" C calling convention you have to care about the stack pointer (esp) (i think it's the callee's responsibility (of the called function)), maybe even the bottom pointer (ebp) (i remember the wikipedia page on calling conventions explains it). The other difference between x86 and amd64 is floating point math, where sse is the default on amd64 and x87 on x86 (x87 works on stacks of numbers, the reverse-polish using a stack way IIRC).

Useful tools are: objdump -d ("-M intel" for the intel notation), strace to trace system calls, and fdbg since GDB can't make sense of a valid ELF file. You can also join the flat assembler and/or nasm forums. I like fasm better then nasm for no strong reason, but nasm is a bit easier.

glhf




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: