Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What was it like to learn x86-64 Assembly? #66

Closed
ErikSchierboom opened this issue Oct 3, 2019 · 8 comments
Closed

What was it like to learn x86-64 Assembly? #66

ErikSchierboom opened this issue Oct 3, 2019 · 8 comments
Assignees

Comments

@ErikSchierboom
Copy link
Member

We’ve recently started a project to find the best way to design our tracks, in order to optimize the learning experience of students.

As a first step, we’ll be examining the ways in which languages are unique and the ways in which they are similar. For this, we’d really like to use the knowledge of everyone involved in the Exercism community (students, mentors, maintainers) to answer the following questions:

  1. How was your experience learning x86-64 Assembly? What was helpful while learning x86-64 Assembly? What did you struggle with? How did you tackle problems?
  2. In what ways did x86-64 Assembly differ from other languages you knew at the time? What was hard to learn? What did you have to unlearn? What syntax did you have to remap? What concepts carried over nicely?

Could you spare 5 minutes to help us by answering these questions? It would greatly help us improve the experience students have learning x86-64 Assembly :)

Note: this issue is not meant as a discussion, just as a place for people to post their own, personal experiences.

Want to keep your thoughts private but still help? Feel free to email me at erik@exercism.io

Thank you!

@Drako
Copy link

Drako commented Oct 8, 2019

  1. Very good. I started with a bad timing as at that moment only two exercises had a test suite. That was fixed very quickly, however. The advice of the mentor was very helpful. godbolt is an online C, C++, etc. compiler displaying the resulting assembly. This is a very helpful tool to get a starting idea on how to do something, if you already know any of the supported languages. I knew the site already, but it was also suggested by the mentor. In the beginning I was mostly writing C++, taking the generated assembly, understanding it and adjusting it. The medium tasks were then purely written from my head, as I got some practice. The final ones were also mostly solved by myself, only getting support from godbolt, if I encountered problems I couldn't solve. Another great helper was GDB (the GNU Debugger) for analyzing segfaults.
  2. It is way more low level and bound to the specific architecture, x86_64 in this case. While you can freely create more variables in higher level languages, you are actually limited to a given set of registers, you have to manage. Also instructions are more low level, but on the other hand have a lot of side effects which allow interesting optimizations. A nice side effect on the personal side is, to get a feeling of the code, that compilers generate and optimizations they apply.

@bergjohan
Copy link
Contributor

How was your experience learning x86-64 Assembly? What was helpful while learning x86-64 Assembly? What did you struggle with? How did you tackle problems?

I think one of the difficult things in assembly is that it's easy to understand what a single instruction does, but it's hard to get an overview of what a group of instructions are actually doing.
Knowing C was helpful, since it's lower level compared to some other high-level languages.
Using Compiler Explorer to try out small code snippets, and see the resulting assembly, was also really helpful. This gives you an understanding in how a particular piece of code could be written in assembly.
Debugging requires you to use a debugger. You can't really trace your program using print statements, since it requires quite a lot of code in assembly.
Other helpful resources are The NASM Manual, the System V Application Binary Interface, and x86 and amd64 instruction reference.

In what ways did x86-64 Assembly differ from other languages you knew at the time? What was hard to learn? What did you have to unlearn? What syntax did you have to remap? What concepts carried over nicely?

Assembly is very different from other programming languages. There are no variables, data types, conditional statements, or loops. Function arguments and return values are passed in registers.
Directly working with memory can be hard if you are new to assembly, but knowing C and pointers helps a lot.
The syntax is also very different from other programming languages, but it's simple, and easy to learn.

@iHiD
Copy link
Member

iHiD commented Oct 28, 2019

There are no variables, data types, conditional statements, or loops.

@ErikSchierboom Good to think about when we consider what we expect all programmers to know.

@ErikSchierboom
Copy link
Member Author

There are no variables, data types, conditional statements, or loops.

@ErikSchierboom Good to think about when we consider what we expect all programmers to know.

Definitely.

@bergjohan
Copy link
Contributor

bergjohan commented Oct 28, 2019

@iHiD @ErikSchierboom Just to clarify, there are other ways to accomplish this.

Instead of variables, we store data in registers, or on the stack.

Instead of data types we use keywords like byte, dword, and qword, to read different sizes of memory. For example, to read a 4 byte integer from memory, we would write:

mov eax, dword [rsi]

Conditional statements are achieved by using jump instructions, for example:

if (x == 1)
  // Do this
else
  // Do that

Could be written as:

  mov eax, x
  cmp eax, 1
  jne .else
  ; Do this
  jmp .endif
.else:
  ; Do that
.endif:

Loops are also achieved by using jump instructions, for example:

for (int i = 0; i < 10; i++)
  // Do something

Could be written as:

mov ecx, 0
.loop_start:
  ; Do something
  add ecx, 1
  cmp ecx, 10
  jl .loop_start

@fawick
Copy link

fawick commented Nov 14, 2019

How was your experience learning x86-64 Assembly? What was helpful while learning x86-64 Assembly? What did you struggle with? How did you tackle problems?

This track must mark the first time that I ever really thought about and manually needed to observe call conventions (and especially System V ABI) and the difference between caller-saved and callee-saved registers. Personally, what helped lot was working other language tracks in parallel. Having already solved some of the same problems in one or more higher-level language allowed me to concentrate on coding in assembly. Most of the time I ignored Compiler Explorer to prevent myself from copying a compiler's work instead of mentally laying out the instructions myself. I often needed to step through the execution of what I wrote to fix bugs, so I came to appreciate GDB on the command line even more.

In what ways did x86-64 Assembly differ from other languages you knew at the time? What was hard to learn? What did you have to unlearn? What syntax did you have to remap? What concepts carried over nicely?

Yikes, so many opcodes and instructions for testing and branching. I really came to miss boolean operators and block statements from higher-level languages. What helped, though, was the clear picture on how arrays are laid out in memory in C, C++, Rust etc.

At first an odd thing to me was the tendency to tip the balance between micro-optimization and readability in hand-written assembly toward faster and smaller code. For example, the typical cmp rax, 0 vs. test rax, rax. Or consider mov rax, 0 vs. xor rax, rax. It's perfectly clear for me now, but reading assembly in the beginning I had difficulties identifying the intent of such a statement.


In closing, I'd like to add that the mentoring in this track was fantastic. All comments and tips for improvement have been very helpful and the tone was encouraging. I really liked that experience!

@modrobert
Copy link

  1. I just finished the "x86-64 Assembly Track" (as student 'rve' at exercism.io) and it was a lot of fun. Big thanks to @bergjohan for teaching me new tricks and being an inspiration to learn more, great mentor. The first language I learned back in 1978 was Basic, shortly after that came assembler for the Z80 and 6502 processors (eventually x86). My approach to tackle the exercises was to use the "Intel® 64 and IA-32 Architectures Software Developer’s Manual (Combined Volumes)" massive PDF which is the closest thing to a complete "datasheet" I could find for the x86-64 CPU family to bring my ancient x86 knowledge up to speed while also realizing how enormous the ISA is now. I struggled mostly with optimization, and the space_age exercise due to my lack of floating point experience in assembly language.

  2. Still having occasional problem with the "right-to-left" direction of x86 opcode syntax (when using 'nasm') as opposed to the 68k family of CPUs. Using 'gdb' to debug carried over nicely from other program languages like C.

I'm not sure if suggestions are appropriate but it would be nice with some "HARD" or "MEDIUM" extra exercises, like for example, a full AES-256 implementation, or something useful like that. ;)

General background ramblings (feel free to ignore):
After nearly 20 years of reverse engineering professionally both hardware and software, and roughly 30 years experience programming different architectures in many different languages dating all the way back to the mainframes (and first micro computers), its' easy to assume your knowledge is sufficient, but it never is, there is always more to learn. The past two decades I made promise to myself to spend at least two hours per day learning something new (physics, electronics, programming, calculus, geology, history, etc.) and lately exercism.io has made that a lot more fun than it used to be regarding the programming part. I don't have much ambition except for my endless hunger to learn more, the dream is to one day be an "expert of many trades", not just a "jack of all trades".

@ErikSchierboom
Copy link
Member Author

We're closing this issue as it was part of our research for the v3 version of Exercism which has just been released.

Thanks everyone for chipping in! It has been greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants