Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prerequisites for learning Assembly Language [closed]

I decided to learn assembly language because I came to know that learning it has many benefits, we can directly interact with the hardware, we can learn how computers better, and much more. When I started to learn it first, I came to know that it was a little bit weird and not like other programming languages so I thought that maybe I will find it hard to learn. So, I'm just asking what are the basic prerequisites for learning assembly language. For information, I have already learnt programming languages like C, C++, C#, PHP.

like image 771
Tanay Karnik Avatar asked Oct 30 '14 16:10

Tanay Karnik


2 Answers

You have to tell us what machine's assembly you want to learn. ARM, x86(_64), Sparc, etc are all different ISAs.

If you just want an introduction to the world of assembly programming in general, Randal Hyde's Art of Assembly is a good one (although what you write isn't exactly assembly, but more of a mix between high and low level languages, it will introduce you to the concept nicely).

If you have set your sights on x86, I can recommend this book: Professional Assembly Language. Apart from that book, sandpile.org is a great resource.

For x86, the choice of environment also matters. Here is a great tutorial for windows assembly programming by the University of Illinois Urbana Champaign ACM student chapter - SIGWINDOWS. For Unix, a great tutorial I have met is this one. A great, more general resource is Reverse Engineering for Beginners by Dennis Yurichev. This book, is targeted at both windows and unix environments, and although it concerns reverse engineering, it can help you learn a great deal about the machinations of programs running on your computer.

For ARM, this article serves as a great introduction. This article is also another great introduction to the matter

like image 86
NlightNFotis Avatar answered Oct 17 '22 08:10

NlightNFotis


I started programming in assembly about two months ago and so far it's gone very well. Let me give a little summary of what I have learned so far.

Syntax

There are two major syntax's for x86 assembly: Intel and AT&T. There are pros and cons to each one. The Intel syntax seems to be only used for x86 based processors whereas the AT&T syntax is used for several different architectures (e.g. ARM). If you look at the source code for OpenBLAS you will see that they use the AT&T syntax for several different architectures. However, many people think the Intel syntax is more readable. So far I have I been programming using the Intel syntax but I know how to read the AT&T syntax to the most part.

Assemblers

You could use inline assembly with GCC but not with MSVC 64-bit. I have not bothered with inline assembly so far. There are several assemblers you can choose from such as: MASM, NASM, YASM, FASM, and GAS. MASM uses only the Intel syntax and is only really used for Windows as far as I understand (I don't think it can be ELF object files for Linux). NASM also uses only the Intel syntax but can create several different object files e.g. for Windows and Linux. YASM as far as I can tell is NASM to the most part but also supports AT&T syntax. FASM uses the Intel syntax and can create several different object files as well but it diverges in several ways from NASM and YASM. I have not used FASM yet but it looks enticing. GAS uses the AT&T syntax (though it's possible to use the Intel syntax ) and is actually what is used when you compile with GCC. GCC produces assembly which is sent to GAS.

It's important to understand that each assembler has it's only dialect so you can't expect code written in MASM to necessarily assemble out of the box in NASM. NASM and YASM to the most part are compatible though as far as I understand.

Which assembler should you choose? I have only used NASM so far.

Calling Conventions and linking with C

The best source for learning assembly for me so far has been GCC. Write code in C and then look at the assembly. For example if you have a simple function foo you can do

gcc -O3 -S foo.c             //AT&T syntax
gcc -O3 -S -masm=intel foo.c //Intel syntax

then look at the file foo.s or you can use objdump

gcc -O3 -c foo.c
objdump -d foo.o             //AT&T syntax
objdump -d -Mintel foo.o     //Intel syntax

You should know the function calling conventions of your OS. The calling conventions are different for 32-bit code and 64-bit code. For Windows and Linux they are the same for 32-bit code but different for 64-bit code. So far I have only written assembly code with NASM for Linux 64-bit.

Many of the assembly questions on SO seem to be about writing entire functions in assembly including user input and output. I don't think this is necessary. Let C take care of the input and output. You can see an example of this an this question. I gave the NASM code and C code and explained how to assembly, compile, and link them. This was one of the first things I wrote in x86 assembly. In that question I had a function

float triad(float *x, float *y, float *z, const int n);

The Linux x86-64 (or rather the System V AMD64 ABI) calling conventions pass the first parameter in the rdi register, the second in rsi and the third it rdx. So in this case rdi=x, rsi=y, rdx=n.

Once you get the calling conventions down and can interface your object files from assembly with C you will find working with assembly a lot easier.

Lastly the second best source for learning assembly for me has been Agner Fog's Optimizing Assembly manual. There is a lot of good advice in the first part of the manual for beginners. And once you get some experience the later part of manual has lots of good information.

like image 44
Z boson Avatar answered Oct 17 '22 10:10

Z boson