Live data from Hacker News

A fundamental introduction to x86 assembly programming

nayuki.io

51–60 of 78 posts

Re: A fundamental introduction to x86 assembly programming

#51
post #4

Adding to my read later. Looks like a good intro. Does anyone know of a similar resource for ARM assembly?

I'm not aware of a good free introduction to ARM assembly, but you could check out the reading lists from these courses:

http://studentnet.cs.manchester.ac.uk/ugt/COMP15111/syllabus... http://studentnet.cs.manchester.ac.uk/ugt/COMP22712/syllabus...

Despite its age, ARM System-on-Chip Architecture (Steve Furber) is still a good introduction to the processor and assembly (I'm re-reading it at the moment). ARM Assembly Language - an Introduction (J.R. Gibson) is worth reading if you want to learn ARM assembly.

The materials page for COMP22712 also has some interesting resources, including the lab manuals and a small ARM assembler written in C (source is also on GitHub: https://github.com/uomcs/aasm). Unfortunately COMP15111 is now hosted on Blackboard so you can only get at the materials if you're a current student enrolled on the course.

(I've been an undergrad, postgrad and staff in CS at Manchester, so I'm familiar with the courses - other universities may have similar resources with fewer access restrictions).

Re: A fundamental introduction to x86 assembly programming

#52

If you want to learn x86 assembly, I recommend one of my favorite books Programming From The Ground Up: http://savannah.nongnu.org/projects/pgubook/ (free pdf!) This is a practical book and teaches assembly programming on Linux. Author Jonathan Bartlett wrote this book because he was frustrated to no end with the existing books. At the end of them he could still ask, "How does the computer really work?" and not have…

For "How does the computer really work?" questions, I recommend this book: http://www.charlespetzold.com/code/

Funny you mention that one. I have been re-reading that book the past few weeks.

This book takes a bit of a different angle on explaining computers. I really enjoy the history.

My only complaint would be that I think he has a Microsoft bias (but then I guess I am biased myself).

And similarly, I have a minor annoyance with the OP's mention of Linux, and only Linux, when he touches on calling conventions. This bias toward one system, and ignorance of others, is typical of many websites and documentation. To be fair, the OP mostly avoids it.

To be clear, great explanations of computers to me are ones that either:

   1) take great care to stay completely neutral and only discuss universally shared traits across systems,

   2) go to great lengths to try to be as comprehensive as possible, including many systems and all their commonalities and idiosyncracies, or

   3) focus only on one system and go into great detail how it works.
The more the author strays from 1, 2 or 3, the less likely I am to read their work.

Petzold pays ample attention to Morse code and similar succinct ways of communicating information. In my opinion this type of focus is the mark of a skilled coder. When I look at the entries to IOCC, it is no surprise to me that Morse code is (or at least was) a frequent focus of the entrants.

Re: A fundamental introduction to x86 assembly programming

#53
post #15

> The way the x87 FP stack works is a bit weird, and these days it’s better to do floating-point arithmetic using xmm registers x87 allows to do calculations in extended precision, i.e. word width is 80 bits. SSE is limited to double precision (64-bit words). Also FPU has some advanced math instructions, like sin, cos, tan, exp, etc., and these operations will be available in AVX512F.

Have fun debugging arithmetic difference resulting from spilling an intermediate result to memory and rounding to 64bit value vs. not spilling and keeping the intermediate value as 80 bits.

Re: A fundamental introduction to x86 assembly programming

#54
post #15

> The way the x87 FP stack works is a bit weird, and these days it’s better to do floating-point arithmetic using xmm registers x87 allows to do calculations in extended precision, i.e. word width is 80 bits. SSE is limited to double precision (64-bit words). Also FPU has some advanced math instructions, like sin, cos, tan, exp, etc., and these operations will be available in AVX512F.

[deleted]

Re: A fundamental introduction to x86 assembly programming

#55
post #39
post #34

A very nice book about assembly programming is "Assembly Language Step-by-Step: Programming with Linux, 3rd edition" ( http://www.amazon.com/dp/0470497025 ). The nice thing about this book is that it guides the reader at understanding how the machine works first, and only then to assembly programming. The sad thing about this book is that it references 32 bit intel-compatible processors. My guess is that the original…

I work in an IT dept which supports almost a dozen departments that all told use about 30 or 40 apps, almost all of which are still 32-bit. The hardware is recent and all 64-bit (as is our OS) but even the MS Office we use is 32-bit because of interaction with other apps. We also have to default the browser to the 32-bit IE executable rather than the 64-bit because of plugins (even MS recommends this). Most vendors s…

When I worked at a university, we had several pieces of legacy 32-bit software, mostly written in C, which were essential to some courses. It became more and more difficult to run them as Linux distributions stopped shipping 32-bit libraries by default (I think Scientific Linux 7.1 caused a lot of problems because of this).

Re: A fundamental introduction to x86 assembly programming

#56
Randall Hyde's work is interesting for beginners and users alike. Art of Assembly teaches you assembly but he uses a high-level assembler to do it in pieces. So, you can abstract away some things like in a HLL to ignore them until you understand enough to use the raw ASM. Likewise, if you use HLA for projects, you can do HLL stuff where understanding is more important than performance/memory. Standard library for HLA is so large the HTML reference about froze my browser haha.

http://www.plantation-productions.com/Webster/

Re: A fundamental introduction to x86 assembly programming

#57
post #17

Earlier quoted context omitted.

I wonder if there is a nice and easy to use x86 simulator like the MARS simulator for MIPS [1]? Some place where I can run (step through) little x86 assembly programs study their effect of the each register. [1] http://courses.missouristate.edu/KenVollmar/MARS/

GDB?

By GDB, you mean the GNU debugger? I have not used it for over a decade. Is it a convenient interface for toying and experimenting with x86 assembler?

Re: A fundamental introduction to x86 assembly programming

#58
post #30

Earlier quoted context omitted.

Yes, The SPARC architecture manual. Punch that into Google or DuckDuckGo and it should be the second link (you want the SPARC V9 instruction set architecture). I would post the link I found, but since I actually have the physical book, I'm uncertain as to whether posting a link to a PDF of a possibly copyrighted book would get me in trouble with Hacker News or not. I've done some SPARC assembler programming for fun,…

How much does the hard copy run you? I am thinking of porting my hobby OS to the architecture so it's probably worth having around in hard copy form.

Prices vary. I might have bought it new off of Amazon for $90, but I don't remember any more.

http://www.amazon.com/SPARC-Architecture-Manual-Version9-Int...

Re: A fundamental introduction to x86 assembly programming

#59
post #50
post #44

I was surprised to read that x64 apparently doesn't allow pushing or popping 32-bit values. I have a language that uses 32 bits as the basic unit for all values and I'm working toward x64 code generation. Should I just promote values to 64 bits and waste half the stack? Should I use mov instructions instead of push/pop? What solutions are other compiler-writers using?

x86-64 is really oriented around integer values being 64-bits. For example, 32-bit operations will zero-extend the result to write the full 64-bit integer register. The ABI also assumes integral values are promoted to 64-bits and the stack is 64-bit aligned on calls. That said, as long as you keep RSP aligned you can do whatever you want. Consider this code: extern void value(int* a, int* b, int* c); int main() { int…

Almost correct.

If you want to call C code conforming to the x86-64 SYSV ABI, RSP needs to be aligned to 16 bytes when you execute the call. If the code you generate never calls alien code, 8 byte alignment is enough.

Since 8 bytes are occupied by return address pushed by the call which started your function, you need to decrease RSP by further 8, 24, 40, 56, 72, ... bytes before calling code generated by others.

Reason: having stack 16 byte aligned makes it easier to allocate aligned 16 byte stack variables and this is useful because x86 has 16 byte registers (SSE) which are most efficiently loaded/stored to aligned addresses.

However, it isn't only performance that you lose by neglecting alignment. I learned the hard way that some code generated by gcc crashes if you call it with unaligned stack.

That's why in this example LLVM allocates 24 bytes, even though 16 would be enough for 3 ints.

Another example (gcc):

  extern void bar();

  void foo() {
          bar();
  }

  0000000000000000 :
   0:   48 83 ec 08             sub    $0x8,%rsp
   4:   b8 00 00 00 00          mov    $0x0,%eax
   9:   e8 00 00 00 00          callq  e 
   e:   48 83 c4 08             add    $0x8,%rsp
  12:   c3                      retq
To anyone writing x86-64 compilers, I recommend finding the x86-64 SYSV ABI spec and reading it. Saves debugging time.

Re: A fundamental introduction to x86 assembly programming

#60

This is a nice fundamental introduction, but where would I go to see how to actually run code?

My best introduction to any asm language is just my C compiler putting out asm (gcc -S, I think). I can create small programs to do what I want, and see what the compiler puts out.

The -S flag also works in clang, although the output may differ. For example, last time I checked a comparison check of i
  cmpl    $9, -4(%rbp)
  jle .L3
under GCC ('if i
  cmpl    $10, -8(%rbp)
  jge .LBB0_4
under clang ('if i >= 10, end the loop'). Neither GCC or clang does an exact conversion, and they both produce different assembly instructions (optimisations disabled in both cases).

If you build a cross-compiler, you can also output assembly for architectures other than your local machine, though this can be quite fiddly (see crosstool-ng for a project which has done most of the work for you).

Post reply on HN