OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 5:14 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 4:01 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
A little rambling topic in between important topics. Let see whether it takes off or not. I have been programming in assembly for some time now and I would like to list some rather obvious advices. This is not a comprehensive list but just a few random thoughts.

  • Usage. Do not write in assembly unless you have a good reason to do so, e.g. a hobby, tool-chain related issues, etc.
  • Modularization. Keep code units rather small. This does not necessarily mean that you need to split procedures into subprocedures but modern assemblers are good at "including" files so build your programs by "including" small units into bigger units. Do not go too far, i.e. avoid long dependency chains.
  • Registers. As far as I know, this is one of the biggest problems. Be absolutely sure which registers are preserved and which are not. It may be convenient to have some kind of "dependency barriers" along the way. For example, "from this point on I know the exact state of the registers and any modifications before this point do not have any effect." It is a form of art to do this with minimum overhead.
  • Calling convention. Related to the previous points. Have a strict calling convention for "public interfaces". Although debatable, I recommend having the "callee saves all but return values" approach. Internal procedures can be rather liberal and that is one of the advantages of assembly programming.
  • Meta programming. Use macros or other helper tools if creating long and repetitive code sections. Usually much less error-prone.
  • Macros, defines, etc. A contradictory topic. Useful if done right. Extremely bad if done wrong. It is easy to vefify the code if you know exactly what it does.
  • Comments. Rules are simple: use comments almost everywhere.

Please add your comments and ideas.

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 6:44 am 
Offline
Member
Member
User avatar

Joined: Mon Mar 05, 2012 11:23 am
Posts: 616
Location: Germany
Aggree to all of these, except:

  • Calling convention. Have a strict calling convention for "public interfaces". Callee saves only registers that it modifies, except the ones used for return.
I think saving all is overkill. You keep track of what registers you modify. I disagree on the internal procedures part; they should follow the same convention, otherwise they could trash stuff. This depends on how you define internal; if public procedure A and public procedure B both might use it, the problems begin.

_________________
Ghost OS - GitHub


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 6:56 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
max wrote:
I disagree on the internal procedures part; they should follow the same convention, otherwise they could trash stuff.


Internal procedures could be like "static functions" in C. It is much more flexible to have loose rules for them.

max wrote:
if public procedure A and public procedure B both might use it, the problems begin.


If those procedures, both A and B, are in the same module, it is possible that both of them use the same internal procedure.

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 7:34 am 
Offline
Member
Member

Joined: Wed Jun 17, 2015 9:40 am
Posts: 501
Location: Athens, Greece
Hi,

Programming in assembly can be entertaining and you might gain something from it, but it can also be sometimes very frustrating. I think this topic isn't really that rambling, but rather useful for everyone programming in assembly.

I agree modules should be small. This way they are more maintainable.

Now, about registers: As Antti said, always make sure which registers are preserved and which are restored. To make sure, push all used registers at the start of the call and restore them when done, so you can remain quiet that they were not altered by the call. The same goes with variables too.

I prefer not using macros, because they add executable code without noticing it. Use calls wherever possible, except you want to optimize your code for speed. Constants are fine.

Always document your code. At each call, document input and output values so you pass these that are needed for the call. Describe carefully what is the function of each register inside each call. Put local labels every 5-10 lines inside each call, that describe what's going on in the next 5-10 lines, even if there are no jumps to them. Comment every single line of code.

Try to write with least lines of code possible. Assembly is generally hard to read (optimized or not), so don't make it even harder by writing lengthy code.

I hope this was useful advise.

Regards,
glauxosdever


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 9:54 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
glauxosdever wrote:
Try to write with least lines of code possible.


It is not always good. For example, sometimes unrolling a short loop can make code much more readable.

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 10:53 am 
Offline
Member
Member

Joined: Wed Jun 17, 2015 9:40 am
Posts: 501
Location: Athens, Greece
Hi,

Antti: Generally, writing less code is most times better, because code that doesn't exist has no bugs and you can maintain it more easily. There are always cases where writing more lines can make code more readable, but these are less usual than the other cases.

You can save lines by avoiding unnecessary CMP instructions. For example a CMP ECX, 0 is pointless after a DEC ECX because DEC instruction will set the zero flag if ECX equals 0.

You can also use registers instead of main memory to store values. Moving a value from memory to memory can't be done in one single instruction, instead a register will be needed between. Writing to registers is faster compared to writing to memory, so for loops that are executed several thousands of times per second, it is really better to use registers for storage; the speedup will be noticeable.

Also, if you want to push general purpose registers all-in-one, you can use the PUSHA/PUSHAD instruction, and to pop them all-in-one, you can use the POPA/POPAD instruction.

There are also other size optimization tricks that I'm not aware now. They could make code not only more readable, but also faster.

Regards,
glauxosdever


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 11:39 am 
Online
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
Quote:
You can save lines by avoiding unnecessary CMP instructions. For example a CMP ECX, 0 is pointless after a DEC ECX because DEC instruction will set the zero flag if ECX equals 0.
Although, in practice, the DEC ECX is probably unnecessary; more likely you would just use a LOOP.
Quote:
Also, if you want to push general purpose registers all-in-one, you can use the PUSHA/PUSHAD instruction, and to pop them all-in-one, you can use the POPA/POPAD instruction.
I would say that it is probably better to PUSH/POP registers individually; you rarely need to save all of them. In any case, the PUSHA/POPA instructions are unavailable in 64-bit mode and I would imagine that those looking to the future will be looking at 64-bit code.


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 11:54 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
glauxosdever wrote:
instead a register will be needed between


There is one trick trick if, for some reason, you want to preserve registers.

Code:
push dword [SOURCE]
pop dword [DESTINATION]


It is good that you brought up the FLAGS register. It is extremely important to know which instructions change flags and which not. For example, the LEA instruction is good if you want to make some simple calculations without changing the FLAGS register.

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Thu Jun 25, 2015 1:09 pm 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
USAGE:
My personal preference is, when I write this;
Code:
    @@: mov     ah, [edi - 1]
        mov     al, ' '
        push    edi
        rep     stosw
        mov      cl,  dl
        inc      ch
        pop      edi

        pop     esi
I see this disassembly
Code:
00000040  8A67FF            mov ah,[edi-0x1]
00000043  B020              mov al,0x20
00000045  57                push edi
00000046  F366AB            rep stosw
00000049  88D1              mov cl,dl
0000004B  FEC5              inc ch
0000004D  5F                pop edi
0000004E  5E                pop esi

So there is a one to one correlation between source and object. WYSIWYG in essence. As my project is focused strictly on X86 and BIOS, tools like FASM & NASM are sufficient and my project is not dependant file systems or shared libraries.

MODULARIZATION:
I don't concern myself too much with size, but keep subject matter contained. As an example, currently I'm working on a comprehensive algo to display text on an 80 x 25 (16 color) display that uses characters (1 - 31) for special functions and formatting in one file. Then there will be another for conversion routines Binary -> ASCIIZ and vise versa.

REGISTERS
As I've done quite a bit of Win32 programming, I've adopted M$ preserve everything except EAX, ECX & EDX. This is predicated entirely on specifics of routine, but it is a general rule of thumb I use. Because of this, I've also adopted CDECL calling convention. LEAVE or MOV ESP, EBP at epilogue is a convenient means by which to make sure stack doesn't get out of control.

I never use macros or any higher level constructs, but amply document my code although previous example doesn't show it.


Top
 Profile  
 
 Post subject: Re: Assembly programming advices and ideas
PostPosted: Fri Jun 26, 2015 12:08 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
glauxosdever wrote:
Also, if you want to push general purpose registers all-in-one, you can use the PUSHA/PUSHAD instruction, and to pop them all-in-one, you can use the POPA/POPAD instruction.


Although this is compact in size, I am not sure whether it is actually faster or not. The real problem comes when your procedures have return values. Usually there are not that much registers you need to push/pop, so single pushes and pops may be better. On x86-64 that is the only option.

_________________
Undefined behavior since 2012


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 139 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group