Assembly language is the mother of all languages (I mean programming languages, of course). It is the original programming language from which all other languages descended (you might argue that machine code is, but that is not really a language strictly speaking).

At the same time, assembly language is also the child of all languages because all other languages are first compiled to assembly language before they can run on the computer. That includes interpreted languages because the interpreter itself is compiled.

When HLL were first invented, the idea was to simplify the job of assembly language programming: You use the compiler to produce assembly language code, then improve the code, then assemble and run.

As more and more people got interested in programming, the art of assembly language started to disappear. At least in relative terms: The percentage of programmers familiar with the art is lower, though the absolute number of assembly language programmers may be actually larger than it was, say 30 years ago.

At any rate, the art of assembly language cannot disappear completely, because if it did computers could no longer evolve: There would be no one able of creating new languages, or at least creating compilers for new languages.

That also means there will always be a need for good assembly language programmers. And the fewer there are, the more valuable they (ahem, we) become. So, if you don't know assembly language (or do, but keep shying away from it), learn it: You may become extremely valuable.

There is a common myth that assembly language is somehow hard to learn. That is not true. I mean, all programming languages are hard to learn at first. The difference is that with most new languages there is a certain continuity: If you know Pascal, C seems like a variety of Pascal. If you know C, C++ is a variety of C, and so on. But assembly language requires you to learn it pretty much from scratch.

But once you really learn it, all other languages start looking silly. They all force you to add an extra layer of abstraction. Once you have mastered ASM, you can code in it as fast as in any other language, and you will soon be paraphrasing Patrick Henry, "Give me assembly language, or give me death!"

Oh, yes, assembly language is more addictive than E2. That's because anything you can do in a HLL you can do in ASM better.

mov ax, @data
mov ds, ax
mov dx, offset ObsceneComment
mov ah, 09h
int 21h
mov ax, 4c00h
int 21h
end
I had to take an Assembly Language for the Intel X86 processor family last semester for my computer engineering degree. At the same time I was taking my first course in C++. Assembly was by far more difficult than C++, but I ended up understanding it better, because I spent more time working on it. Also when my C++ classmates were having trouble understanding the concept of a pointer I was wondering how stupid people could get. In any case I guess I now find I can currently do more with Assembly than C++.

;How to have fun with Assembly.

;I wrote this to be assembled with MASM

;I have never tried assembling this program or running it .model small

.stack 100h

.data

.code

Begin: mov es,0000h

mov di,0000h

mov cx,FFFFh

mov al,FFh

L1: Push cx

inc es

mov cx,ffffh

L2: stosb

loop L2

pop cx

loop L1

mov ah,4ch

int 21h

End Begin

Assembly is much more fun with RISC processors. For example, here is some MIPS assembly to do multiplication. Yes, I realise that MIPS assemblers provide a multiply pseudo-instruction, which uses the hardware multiplier and is thus much faster than this code. It was for a class, okay?

# multiply:  Multiply two signed 16-bit integers using Booth's
#            algorithm.  The multiplier and multiplicand should
#            be in $a0 and $a1; they should be no larger than
#            16 bits.  The 32-bit product is placed in $v0.
#

multiply:
        ## $v0 holds the product.  $a0 and $a1 hold a and b, the
        ## multiplicand and multiplier.  $t0 holds i, $t1 holds
        ## the bit most recently shifted off result (called
        ## `shifted').  $t2 holds a in the upper half, 0 in the
        ## lower half; for efficiency reasons, we compute this
        ## value once and save it, rather than computing it each
        ## time through the loop.  Finally, $t3 and $t4 are used
        ## as temporary registers.
        
        ## First set the low 16 bits of result to the multiplier
        move $v0, $a1              # $v0 (result)
        andi $v0, $v0, 0x0000ffff  # clear top 16 bits

        move $t1, $0            # $t1 = shifted
        sll $t2, $a0, 16        # shift a into $t2's high 16 bits

        move $t0, $0            # initialise i
loop:   slti $t3, $t0, 16       # $t3 = (i < 16)
        beq $t3, $0, end_l      # if (i >= 32) goto end_l

        andi $t3, $v0, 1        # $t3 = LSB of result

        ## Do arithmetic based on the shifted-off bit and the
        ## LSB of result.  We perform the operations:
        ##
        ## LSB shifted   action
        ## -----------------------------
        ##  0     0      none
        ##  0     1      add a to result's high 16 bits
        ##  1     0      subtract a from result's high 16 bits
        ##  1     1      none
        ##
        ## Note that we add a to the high 16 bits of result by
        ## adding $t2 (a << 16) to result.  Because $t2's low 16
        ## bits are zero, the low 16 bits of result are not
        ## affected.
        
        ## LSB > shifted:  bit pattern 10: subtract
        slt $t4, $t1, $t3       # $t4 = (shifted < lsb)
        beq $t4, $0, skip1      # if (shifted >= lsb) goto skip1
        sub $v0, $v0, $t2       # subtract a from high half of result
        j skip2                 # next test will always fail
skip1:
        ## LSB < shifted:  bit pattern 01: add
        slt $t4, $t3, $t1       # $t4 = (lsb < shifted)
        beq $t4, $0, skip2      # if (lsb >= shifted) goto skip2
        add $v0, $v0, $t2       # add a to high half of result
skip2:
        ## LSB = shifted:  bit pattern 00 or 11: do nothing

        # We now perform an arithmetic right shift of result by
        # one bit.  The lost bit is stored in shifted ($t1).

        andi $t1, $v0, 1        # shifted = low bit of result
        sra $v0, $v0, 1         # shift result by 1 bit

        # End of loop
        add $t0, $t0, 1         # increment i
        j loop                  # repeat
end_l:
        
        jr $ra
The references to `i', `a', `b', etc. refer to the C version, which i do not include here.

The excessive documentation is due to the fascist instructor. He informed us that we had to comment every single line. This is why EE professors should not teach programming.

Also a language that can shock anyone
with the small size of its runnable output.


I wrote this a very long time ago, in a place
far, far away.





Now, the hard way.


compile this one in tasm, and you'll have a
nice day indeed.

Replace ( with left  square bracket
Replace ) with right square bracket

tasm happy_face.asm
tlink /t happy_face.obj




-----------------happy_face.asm--------------------

 Ideal
 Model Tiny
 CodeSeg
 P286
 Org 256
 Proc Program
;--------------------------------------------------------
              push 0A004h  ;---centered for no extra bytes :)
               pop ds
               mov cl,169  ;hmm.. dunno if ch is clear
               mov al,19
               int 10h
               mov ah,100
               mov dx,2*256 ;this is bad
Curves_Loop:   sub dx,6
               add ax,dx
             pusha
              call yo
               mov [bx],cl             ;lower face
               not bx
               mov [bx-85],bh          ;upper face
               shr ah,1
               shr cl,1
              call yo
               mov [bx+19884],cl
;smile (same shape as lower face)
              popa
              loop Curves_Loop
               mov 𖏠*256],ax
               mov 𖏠*256+50],ax
Keyboard_Wait: mov ah,1
               int 16h
                jz Keyboard_Wait
               mov ax,3
               int 10h         
;program runs over into yo, hits ret (woohoo!)
;--------yo should be rewritten!!! should be able
;to get smaller--------
yo:
               xor bh,bh
               mov bl,ah
               shl bx,6
               add bl,cl
               adc bh,ah
               ret
EndP           Program
End Program

obfuscated assembly language

Assembly language without comments or symbol names. This is what all programs eventually end up as. But why let a compiler have all the fun? Just open up your favorite boot monitor or low-level debugger and start tapping away (on the numeric keypad for the really ambitious) a new kernel or window manager or anything else.


Well, yes, there is the practical side of it all...
The first assembler I learned was x86. Turned out to be good for optimization sometimes, but not really that useful in the long run. Intel has so many instructions just for backward compatibility that it's quite a pain to master and it is quite a challenge to write readable code.

But, assembly language for the PIC microcontroller is a whole different story. Because of the PIC's very limited memory assembler is the only way to go. Because most of the PIC series controllers have less than 40 instructions, it's very readable and easy to program. Obfuscating PIC assembler is more of a challenge, when in x86 assembler it's a way of life.

Log in or register to write something here or to contact authors.