# Trying to learn  ASM



## hockey97 (Jan 7, 2013)

Hi, I am trying to learn ASM x86 32 and 64 bit systems. I found many books and pdf files and websites talking about this but many use their own choice of assembler. 

I downloaded and installed NASM. I would like to learn ASM in NASM but fail to get a book or tutorial that would show ASM code or explanations in NASM. Most are always in MASM and sometimes they do mix both MASM and NASM. 

I would like to start learning the language. Anyone know of any great ASM programming books that are fairly recent meaning upto date and is explaining concepts in NASM or showing examples in NASM.


----------



## drhowarddrfine (Jan 7, 2013)

With anything FreeBSD, there's a handbook for that: FreeBSD Assembly Language using Nasm


----------



## throAU (Jan 8, 2013)

I know a little x86 assembly (from back in the DOS days, in-lining it in Turbo Pascal), and I'd suggest that "learning assembly" isn't like learning a language like say, C or Pascal.

Due to it's low level nature, to get much done you actually need to know more than assembly language.  You need to have a firm grasp of how to call functions in your operating system and how to talk to the hardware.

You'll also need a firm understanding of binary math, the concept of pointers, etc.

Also, as you have discovered - assembly language syntax varies, depending on the assembler you are using.

Work out what you want to learn assmbly FOR, and then figure out what hardware and operating system libraries you'll need to interact with and read up on those as well.


You may find it easier to learn a simpler assembly language first - back when I was in university we used Motorola 68HC11 development kits - the CPU/instruction set is much simpler because you were pretty much running directly on the hardware there were far less hoops set up by the operating system to jump through to get anything done.

edit:
these days, maybe pick up a Rasberry Pi and learn ARM assembly?  ARM is a much "cleaner" architecture than x86 and I suspect may be easier to start off with.


----------



## hockey97 (Jan 8, 2013)

throAU said:
			
		

> I know a little x86 assembly (from back in the DOS days, in-lining it in Turbo Pascal), and I'd suggest that "learning assembly" isn't like learning a language like say, C or Pascal.
> 
> Due to it's low level nature, to get much done you actually need to know more than assembly language.  You need to have a firm grasp of how to call functions in your operating system and how to talk to the hardware.
> 
> ...



Ya, I know about binary math and the concept of pointers. I know C and C++. I have made simple windows programs using win32 api but never made system calls or anything low level.

I did read a ASM book on linux ASM programming and they had a chapter on system calls. 

They explained that system calls are nothing but actual calls to the kernal itself. However, windows don't allow this. They said that windows will put you in protected mode which forces you to use their api which the api then does the system calls to the kernal.

I don't know how true but the book said that DOS and linux don't put you in protected mode. It allows you to directly do system calls to the kernal.

I do know how to build computer circuits and did take a class on it. Did learn ohms law etc. I have made my own 4-bit cpu and 32-bit cpu. It didn't do anything cool but I made it do many functions.

I had built a radio ya it works I can tune into real stations. I built a binary counter and built circuits in analog and digital.  I even built a analog to digital converter and the reverse of that too.

Ya, I know the syntax varies depending on the assembler... I know there is NASM,MASM,FASM,TASM. 

I already read a few books some about hacking which had ASM. I read the books since I was recommended to read them since it had a few chapters on assembly. 

I know the numbering systems like binary which is based 2 and hexadecimal which is 16 base and decimal system is 10 based. then octal is 8 base and then there is a 9 based numbering system called Nonary and there is a 3 based numbering system called Ternary and 12 based numbering system is duodecimal.

I took electronic classes in highschool that was college equivalent. I built my own cpu's and created my own opcodes.

I already went thru the basics and do know some operations like add,mov,push,pop,cmp,jmp,call...etc..

I currently don't understand how to interact with an OS. I did start learning windows.
I was told you would need to use the call operation to call C functions / classes etc.
I would have to use the windows win32 api to make windows software for windows.

I haven't done this physically other then create a hello world in text with an ok button and a windows window something very basic.

yet, there is still alot that I don't know or understand. I haven't read books that goes into detail about ASM and making software or drivers for an OS. 

I am pretty sure I can handle ASM. I think I have a good enough background to understand the material. I just need a book or a tutorial that can explain system calls and working with the kernal or win32 api. I was told that the win32 api isn't different then how you would use it in C or C++. It's the same functions. 

However, I would still need someone to explain to me the ASM code. Since it's not like C or C++. Like I done labs so far. The ASM window application had @16 messagebox A  something like that.

I had to ask people online what it does. I was told It was used to be capable with DOS predecessors. So I would need to use it or else I would get some nice errors.

Anyways, thanks for the replies. I will look into anything that is suggested. I am pretty sure I can handle ASM. I have the will and the desire to learn it.


----------



## kpa (Jan 8, 2013)

Couple of points. 

There are no constructs for easy loops or conditional statements like you find in higher level languages. All branching is done by testing a flag after an operation and jumping forwards or backwards depending on what you need to do.

You'll be doing lots of byte nibbling and byte order must be clear in your head all the times.

You have to save the working registers on the stack before calling a subroutine that might use those registers.


----------



## kpedersen (Jan 8, 2013)

Whilst I generally know enough assembly to patch away DRM in Windows software, I don't know much about writing entire programs with it. I might suggest using C and then inline the ASM. A pure asm compiler would be pretty hostile to learn on.

i.e


```
void some_func()
{
  __asm__ ("movl %eax, %ebx\n\t"
           "movl $56, %esi\n\t"
           "movl %ecx, $label(%edx,%ebx,$4)\n\t"
           "movb %ah, (%ebx)");
}
```

This way, you can call C functions too for eas(ier) debugging.

Perhaps the following tutorial would be good?

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html


----------



## drhowarddrfine (Jan 8, 2013)

It's what you're used to. I started life as an EE so assembly was in my blood. One place I worked, our boss forced us to learn this C language thing and we hated it. We could do so much more so much easier in assembly. But I got used to it years later.


----------



## Beastie (Jan 8, 2013)

Assembly has always been my favorite language!

You mentioned FASM briefly; have you considered using it? It's an excellent assembler, it's actively being developed, well-documented, features an elaborate macro language, and there's even an ARM version.

In addition to the Developers' Handbook chapter drhowarddrfine already mentioned, there's also http://www.int80h.org/.


----------



## graudeejs (Jan 8, 2013)

You can also check my sample code (32bit)
https://github.com/graudeejs/asm4BSD

It also has lang/fasm headers for *BSD

I find this https://github.com/graudeejs/asm4BSD/tree/master/FreeBSD/examples/RTU the most interesting example


----------



## hockey97 (Jan 8, 2013)

kpa said:
			
		

> Couple of points.
> 
> There are no constructs for easy loops or conditional statements like you find in higher level languages. All branching is done by testing a flag after an operation and jumping forwards or backwards depending on what you need to do.
> 
> ...



Isn't flags the same as states,events? I do know about flags but like I said I don't know alot but from reading from books. You always check them they don't explain or how it's treated but from sample code I assume it's used like a event or a state.

For instance the mouse it has a x and y event. those values would keep changing based on the mouse movement detection.  I assume flags in ASM is the same concept but more of a low level end use.


----------



## hockey97 (Jan 8, 2013)

Beastie said:
			
		

> Assembly has always been my favorite language!
> 
> You mentioned FASM briefly; have you considered using it? It's an excellent assembler, it's actively being developed, well-documented, features an elaborate macro language, and there's even an ARM version.
> 
> In addition to the Developers' Handbook chapter drhowarddrfine already mentioned, there's also http://www.int80h.org/.



I haven't looked at it. I have only looked at MASM and NASM and I already have NASM installed on my machine and have made a windows program from it. Well a hello world using the win32 api. Very basic simple app. So I am  at a point where I am used to it.

The reason I picked NASM was that I found board forums that I talked to about ASM and most suggested NASM and said there are alot of tutorials and reading material online.

I did find tutorials and alot of books talking about it... however, I have mostly seen books talk about MASM. However, I only seen books either talk about NASM or MASM but most of the time they will talk only about MASM.

So, I picked NASM and downloaded and installed the assembler and then learned how to use it and how to assemble code. 


I would like to learn main stream Assemblers. I don't want restrictions. So if NASM is multiple use for other OS'S or machines it's a plus. I was told that MASM is only for windows and x86 machines. 

I never liked microsoft and MASM I feel is more geared to Microsoft products and fear that it will restrict me to those products only.

I would like to learn what is industry standard and is popular. I know C and C++. The reason I learned C++ was that I am told it's the Industries leader programming language to be used to make software.

The reason I want to know the popular languages so my skills can have potential to lead to a job. I mean if I learn something that is outdated or not popular in the industry then it be useless to know it since you can't really get a job with that skill set.

So, I was told that NASM is the popular one well Both NASM and MASM but NASM is popular choice when you need  to do ASM for many different OS'S or hardware etc. MASM is popular if you want to just make drivers and apps for windows OS machines. I was told it's more strictly used for microsoft products. 

That is why I decided to use NASM. The problem is that there isn't that much documentation to learn how to use NASM or how to write an app or software with it.

I have seen books talking parts not going in detail like they would talk about flags and other stuff but won't talk in the sense as if the person never touched ASM code before. So they don't go into detail what flags are and how you use them just will tell you to use them for comparing or when you need to find out a state.


Do you think FASM is worth learning? I think for now I will stick with NASM. Unless you can convince me that FASM is more popular and used that learning it could land me a job.


----------



## throAU (Jan 9, 2013)

First up - Linux DOES run in protected mode on the x86, it needs to run in protected mode to get flat memory access rather than dealing with the old segmented memory model.  There are still segments in 32 bit protected mode, they're just 4gb in size rather than 64k.  Have had nothing to do with x64 so no idea if they still exist - perhaps they're 2^64 in size and are still there also.


TASM/MASM/FASM/etc are all just slightly different syntax for the same assembly language.

If you learn one, you should be able to easily pick up/use another.  The opcodes will be the same, but things like the operand order may differ depending on the heritage of the assembler.

To be honest, I would recommend learning how to use in-line assembler in C/C++ programs, as this is likely to be more likely what you'll be doing (in a job) in the x86/x64 world these days.  If you're wanting to work in embedded devices and want assembly for that, ARM is far more popular in that market.

The job market for pure x86/x64 assembly is going to be exceedingly small.

By all means play with a dedicated assembler, but I wouldn't bother learning a heap of them.  Learn the core *concepts* (i.e., how to structure assembly language, how to get what you need to do done with the limited control structures you have, how to call into the kernel or libraries on your OS of choice, etc), move on.

In the real world, unless you're working on embedded devices, a compiler or a boot loader, you're likely to be working in C or C++ and maybe optimizing small hot-spots in the program in assembler if required.


Even if YOU like assembler, the rest of your team will also need to maintain the code.

Honestly, if employment prospects are a primary concern - I'd be considering languages more related to the business world.  The job market for assembly language programmers these days is fairly small.

Also, assembler on the x86/x64 platform is a moving target.  Unless you're going to learn all the new CPU features every time they come out, and also learn the specific optimization tricks for each new generation of CPU you're going to have trouble keeping up with code generated by a modern optimizing compiler that does.

Instead of, for example the C/C++ guy flicking a compiler flag after applying an update to his compiler - to enable say, AES-NI support, you'll need to manually write a feature detection check (in assembler), and write an additional code path for the new CPU features, then debug/test/etc.

Not saying don't learn assembler - just be aware of when it is appropriate.  Writing entire desktop applications in x86 assembler is just not appropriate any more.

Put it this way - download a copy of the Linux or FreeBSD kernel source.  Check out how much of it is assembler.  You'll find it is mostly C.  And that's an operating system kernel - not an application.  

Applications are even more biased towards high level languages.


Again, don't get me wrong - not trying to say you're wrong to learn it.  Just trying to illustrate how common assembly language programming is in the real world these days (it's not).


----------



## kpa (Jan 9, 2013)

hockey97 said:
			
		

> Isn't flags the same as states,events? I do know about flags but like I said I don't know alot but from reading from books. You always check them they don't explain or how it's treated but from sample code I assume it's used like a event or a state.
> 
> For instance the mouse it has a x and y event. those values would keep changing based on the mouse movement detection.  I assume flags in ASM is the same concept but more of a low level end use.



No. The flags are internal one bit registers in the CPU. An instruction that tests if the contents of a register (or contents of a memory address) is zero sets a flag if the test is true. You then use an instruction that jumps to an offset in your program depending on the value of the flag.

Sorry for being slightly vague. I learned some motorola 68000 asm back in the day but I can't express the concepts well enough in i386 asm.


----------



## throAU (Jan 9, 2013)

^^ As above, the x86 CPUs have a flags register.  comparison, addition, subtraction, interrupts, etc. will set or reference bits set in this register.  see here.

You do a branch something like (my x86 asm is rusty and there are shortcut commands for this, but for clarity)


```
sub cx,1
cmp  cx,0
je CXisZero:
```

The je command checks the flags register for the "zero" flag (which was either set or not set by the compare operation) and if it is zeroed out, jumps to the label CXisZero:


edit:
Whatever assembler you use, there is roughly a 1:1 mapping between machine instructions and assembly language mnemonics.


----------



## drhowarddrfine (Jan 9, 2013)

hockey97 said:
			
		

> I never liked microsoft and MASM I feel is more geared to Microsoft products and fear that it will restrict me to those products only.


Masm only runs on Windows and is a Microsoft product with all the licenses and restrictions of Windows.


----------



## Beastie (Jan 9, 2013)

hockey97 said:
			
		

> I would like to learn what is industry standard and is popular.
> [...]
> The reason I want to know the popular languages so my skills can have potential to lead to a job. I mean if I learn something that is outdated or not popular in the industry then it be useless to know it since you can't really get a job with that skill set.
> [...]
> So, I was told that NASM is the popular one well Both NASM and MASM but NASM is popular choice when you need  to do ASM for many different OS'S or hardware etc.


1. You can program anything in assembly, including entire operating systems (e.g. KolibriOS, DexOS, etc.) but the fact is *nowadays its use in the industry is very limited*.
2. Popular is not necessarily synonymous with quality.
3. Consider Java.



			
				hockey97 said:
			
		

> I have seen books talking parts not going in detail like they would talk about flags and other stuff but won't talk in the sense as if the person never touched ASM code before. So they don't go into detail what flags are and how you use them just will tell you to use them for comparing or when you need to find out a state.


In that case, it's not just a book you need; it's THE reference you need: Intel's software developer manuals.



			
				hockey97 said:
			
		

> Do you think FASM is worth learning?


There isn't that much learning to do. Its syntax is not very different from NASM's so if you already know NASM you can just as well try FASM.

As I already said, FASM features an elaborate macro language. It can program ARM devices. It has an excellent and detailed documentation.

It doesn't need a linker.

Everything can be controlled from the source file itself without using countless command-line options.

Being written in its own assembly syntax (unlike anything else), it's lightweight and fast. This also means it's auto-assemblable.

Unlike other assemblers and compilers, it does not optimize code, so code is easier to debug.


----------



## hockey97 (Jan 11, 2013)

throAU said:
			
		

> ^^ As above, the x86 CPUs have a flags register.  comparison, addition, subtraction, interrupts, etc. will set or reference bits set in this register.  see here.
> 
> You do a branch something like (my x86 asm is rusty and there are shortcut commands for this, but for clarity)
> 
> ...




Does that flag get reset when there is a new compare operation? 

Thanks for the explanation. I never found any book that explained the flags. They would say  that it would set a flag and I think they did say zero flag but there is are flags too. Just they never went into detail on explaining what they're for and why use them.


----------



## dennis714 (Aug 13, 2013)

Another quick introduction to ARM assembly and reverse engineering: http://yurichev.com/writings/RE_for_beginners-en.pdf


----------



## throAU (Aug 15, 2013)

hockey97 said:
			
		

> Does that flag get reset when there is a new compare operation?
> 
> Thanks for the explanation. I never found any book that explained the flags. They would say  that it would set a flag and I think they did say zero flag but there is are flags too. Just they never went into detail on explaining what they're for and why use them.



Sorry, missed this.

Yes, the flags get reset after a compare.  If you want to save the state of them (e.g., you're in a nested loop or doing something recursive), you will need to push them to the stack with:

```
pushf
```

(I think that's the mnemonic for push flags; it's been a while and may even be assembler dependent) and pop them back off to get them back.


----------



## numpad5 (Aug 28, 2013)

_It's f_airly easy to compile C source code to .S and read what the C code assembled to before full compilation.


----------

