Here are frequently asked questions (with answers) about Linux assembly programming. Some of the questions (and the answers) were taken from the the linux-assembly mailing list.
An answer from Paul Furber:
Ok you have a number of options to graphics in Linux. Which one you use depends on what you want to do. There isn't one Web site with all the information but here are some tips: SVGALib: This is a C library for console SVGA access. Pros: very easy to learn, good coding examples, not all that different from equivalent gfx libraries for DOS, all the effects you know from DOS can be converted with little difficulty. Cons: programs need superuser rights to run since they write directly to the hardware, doesn't work with all chipsets, can't run under X-Windows. Search for svgalib-1.4.x on http://ftp.is.co.za Framebuffer: do it yourself graphics at SVGA res Pros: fast, linear mapped video access, ASM can be used if you want :) Cons: has to be compiled into the kernel, chipset-specific issues, must switch out of X to run, relies on good knowledge of linux system calls and kernel, tough to debug Examples: asmutils (http://www.linuxassembly.org) and the leaves example and my own site for some framebuffer code and tips in asm (http://ma.verick.co.za/linux4k/) Xlib: the application and development libraries for XFree86. Pros: Complete control over your X application Cons: Difficult to learn, horrible to work with and requires quite a bit of knowledge as to how X works at the low level. Not recommended but if you're really masochistic go for it. All the include and lib files are probably installed already so you have what you need. Low-level APIs: include PTC, SDL, GGI and Clanlib Pros: very flexible, run under X or the console, generally abstract away the video hardware a little so you can draw to a linear surface, lots of good coding examples, can link to other APIs like OpenGL and sound libs, Windows DirectX versions for free Cons: Not as fast as doing it yourself, often in development so versions can (and do) change frequently. Examples: PTC and GGI have excellent demos, SDL is used in sdlQuake, Myth II, Civ CTP and Clanlib has been used for games as well. High-level APIs: OpenGL - any others? Pros: clean api, tons of functionality and examples, industry standard so you can learn from SGI demos for example Cons: hardware acceleration is normally a must, some quirks between versions and platforms Examples: loads - check out www.mesa3d.org under the links section. To get going try looking at the svgalib examples and also install SDL and get it working. After that, the sky's the limit. |
There's an early version of the Assembly Language Debugger, which is designed to work with assembly code, and is portable enough to run on Linux and *BSD. It is already functional and should be the right choice, check it out!
You can also try gdb ;). Although it is source-level debugger, it can be used to debug pure assembly code, and with some trickery you can make gdb to do what you need. Here's an answer from Dmitry Bakhvalov:
Personally, I use gdb for debugging asmutils. Try this: 1) Use the following stuff to compile: $ nasm -f elf -g smth.asm $ ld -o smth smth.o 2) Fire up gdb: $ gdb smth 3) In gdb: (gdb) disassemble _start Place a breakpoint at _start+1 (If placed at _start the breakpoint wouldnt work, dunno why) (gdb) b *0x8048075 To step thru the code I use the following macro: (gdb)define n >ni >printf "eax=%x ebx=%x ...etc...",$eax,$ebx,...etc... >disassemble $pc $pc+15 >end Then start the program with r command and debug with n. Hope this helps. |
An additional note from ???:
I have such a macro in my .gdbinit for quite some time now, and it for sure makes life easier. A small difference : I use "x /8i $pc", which guarantee a fixed number of disassembled instructions. Then, with a well chosen size for my xterm, gdb output looks like it is refreshed, and not scrolling. |
If you want to set breakpoints across your code, you can just use int 3 instruction as breakpoint (instead of entering address manually in gdb).
If you're using gas, you should consult gas and gdb related tutorials.
Definitely strace can help a lot (ktrace and kdump on FreeBSD), it is used to trace system calls and signals. Read its manual page (man strace) and strace --help output for details.
Noway. This is protected mode, use OS services instead. Again, you can't use int 0x10, int 0x13, etc. Fortunately almost everything can be implemented by means of system calls or library functions. In the worst case you may go through direct port access, or make a kernel patch to implement needed functionality.
Yes, indeed it is. While in general it is not a good idea (it hardly will speedup anything), there may be a need of such wizardy. The process of writing a module itself is not that hard -- a module must have some predefined global function, it may also need to call some external functions from the kernel. Examine kernel source code (that can be built as module) for details.
Meanwhile, here's an example of a minimum dumb kernel module (module.asm) (source is based on example by mammon_ from APJ #8):
section .text global init_module global cleanup_module global kernel_version extern printk init_module: push dword str1 call printk pop eax xor eax,eax ret cleanup_module: push dword str2 call printk pop eax ret str1 db "init_module done",0xa,0 str2 db "cleanup_module done",0xa,0 kernel_version db "2.2.18",0 |
The only thing this example does is reporting its actions. Modify kernel_version to match yours, and build module with:
$ nasm -f elf -o module.m module.asm |
$ ld -r -o module.o module.m |
Now you can play with it using insmod/rmmod/lsmod (root privilidged are required); a lot of fun, huh?
That's all for now, folks.