Earlier quoted context omitted.
> Also, I like how returning 0 is "xor eax, eax". Why is it so different with different optimisation levels? The default emits quite a bit of code, -O1 is `mov eax, 0`
> > Also, I like how returning 0 is "xor eax, eax". > -O1 is `mov eax, 0` Simply because it is shorter: On x86-64 (and x86-32) xor eax,eax encodes as 31h C0h or 33h C0h (depending on the assembler; typically the first one is used) - 2 bytes, while mov eax,0x0 encodes as B8h 00h 00h 00h 00h - 5 bytes. Having privately analyzed some 256b demos I cannot even imagine how one could even come to the idea to use `mov r32, i…
Learning to Read X86 Assembly Language
181–190 of 238 posts
Re: Learning to Read X86 Assembly Language
#182Earlier quoted context omitted.
Here are the opcodes for the x86 ADD assembler instruction: http://www.mathemainzel.info/files/x86asmref.html#add The link shows nine ways to use the ADD instruction with each method resulting in a different opcode.
There's a bit of a miscommunication going on. What I meant was, when you write an assembly instruction, that maps to one machine instruction. I.e., because of things like addressing modes, different invocations of an ADD instruction can map to different machine instructions. But one ADD invocation will always map to one machine instruction. The parent comment sounded to me like one assembly instruction could map to s…
That's not true on x86-16, x86-32 and x86-64. For example
060o, 310o
and 062o, 301o
(...o means "octal"; for the reason why I give this example in octal instead of hexadecimal cf. https://news.ycombinator.com/item?id=13051770) both stand for "xor al, cl" (the assembler you use will one of the two encodings) - for those people who really prefer hexadecimal here: It corresponds to 30h, C8h
and 32h, C1h
The fact that there are different ways to encode some instructions was used by the A86 assembler (https://en.wikipedia.org/w/index.php?title=A86_(software)&ol...) to watermark machine code that was generated by it; in particular to detect whether it was generated by a registered or unregistered version of A86:"The assembler automatically embeds a "fingerprint" into the generated code through a particular choice of functionally equivalent instruction encodings. This makes it possible to tell if code was assembled with A86, and also to distinguish between registered and unregistered versions of the assembler, although access to the source code is required."
Re: Learning to Read X86 Assembly Language
#183Earlier quoted context omitted.
Fair enough, some instructions have many variants. But I work with ARM assembly almost daily and I still wouldn't remember that, for example, 'VQRDMULH' is a real instruction and it stands for 'Vector Saturating Rounding Doubling Multiply Returning High Half'.
Ah, yes. A fun one. Those exist in x86, too. I should probably count up x86 against ARM, so I have more than guesses to go on here. Maybe that part of x86 actually better.
It is not easy to tell how many instruction there actually are on x86:
> https://fgiesen.wordpress.com/2016/08/25/how-many-x86-instru...
Re: Learning to Read X86 Assembly Language
#184If you're experimenting with asm in crystal, you might want to use --prelude=empty to remove the standard library to make the asm output cleaner. You can then then require lib_c and use that directly.
I suppose this could work if, as you suggest, I manually called out to a lib_c function like printf instead.
Re: Learning to Read X86 Assembly Language
#185Earlier quoted context omitted.
> > Also, I like how returning 0 is "xor eax, eax". > -O1 is `mov eax, 0` Simply because it is shorter: On x86-64 (and x86-32) xor eax,eax encodes as 31h C0h or 33h C0h (depending on the assembler; typically the first one is used) - 2 bytes, while mov eax,0x0 encodes as B8h 00h 00h 00h 00h - 5 bytes. Having privately analyzed some 256b demos I cannot even imagine how one could even come to the idea to use `mov r32, i…
It's not just shorter, it's also faster. But see my answer also: there are condition flag implications of using XOR and sometimes MOV will be preferable. The optimiser will always know best :)
If the condition flags have to be preserved, you are right. But otherwise, read the linked article (https://randomascii.wordpress.com/2012/12/29/the-surprising-...):
"On Sandybridge this gets even better. The register renamer detects certain instructions (xor reg, reg and sub reg, reg and various others) that always zero a register. In addition to realizing that these instructions do not really have data dependencies, the register renamer also knows how to execute these instructions – it can zero the registers itself. It doesn’t even bother sending the instructions to the execution engine, meaning that these instructions use zero execution resources, and have zero latency! See section 2.1.3.1 of Intel’s optimization manual where it talks about dependency breaking idioms. It turns out that the only thing faster than executing an instruction is not executing it."
Re: Learning to Read X86 Assembly Language
#186x86 is the worst ISA. If you want to play with assembler without feeling a desire to stab yourself and end it all, I recommend ARM. Or go learn Z80, x86's weird, 8-bit cousin (it had a 16-bit version, but it sold poorly), which had a greater emphasis on backwards compatability (you can run code from the original 8080 on a Z80, unchanged), and is nicer to work with (because it wasn't extended in unticipated directions…
> There are only two common reasons to learn Z80 assembler, though: to program the Gameboy [...] and to program a TI calculator What about the myriad of other (mostly vintage) computer systems and video game consoles out there? ;) Sega Master System and Game Gear, for example.
http://gbdev.gg8.se/wiki/articles/CPU_Comparision_with_Z80
As an aside: most of the old, classic 8-bit micros are complete pains to write modern code for, because modern programming languages all assume fast stacks. The Z80 has no stack-relative addressing, which means you need to reserve a precious index register as a frame pointer at the top of every function, and then indirect off that --- but the Z80 designers didn't realise that people would want to do it so often and as a result it's verbose, deal slow, and doesn't handle 16-bit values. So you need to do:
ld h, [iy+8]
ld l, [iy+9]
...for a total of 8 bytes of code and lots of cycles.The Game Boy processor (which doesn't have a snappy name) allows this:
ld hl, sp+8
ldi a, [hl] // load and increment
ld l, [hl]
mov a, h
...which is (IIRC) five bytes. Still not great, but shorter, and also loads faster.If you look at the instruction encodings, the Z80's actually a pile of nasty hacks. The original 8080 is way more elegant; and there's lots of software and tooling for it, too. (But it still can't run C efficiently.)
Re: Learning to Read X86 Assembly Language
#187Earlier quoted context omitted.
This. The AT&T syntax for x86 thing is a huge mistake. All the official docs are Intel syntax. Intel syntax is easier to read and write. Half the gotchas in this article are problems that don't exist in Intel syntax, like the instruction suffixes. The instruction suffixes get even weirder when you get to the sign extending instructions. I wrote an article about this here: http://blog.reverberate.org/2009/07/giving-up…
The AT&T syntax for x86 thing is a huge mistake. For someone who grew up on normal processors (MC68000 and UltraSPARC) AT&T syntax is the best thing since sliced bread: it's perfectly logical to move something to somewhere, instead of "move to somewhere something".
Also, "move destination, source(s)" is consistent regardless how many sources there are (although I agree with you that "source -> destination" is more intuitive for us left-to-right people).
Re: Learning to Read X86 Assembly Language
#188Earlier quoted context omitted.
There's a bit of a miscommunication going on. What I meant was, when you write an assembly instruction, that maps to one machine instruction. I.e., because of things like addressing modes, different invocations of an ADD instruction can map to different machine instructions. But one ADD invocation will always map to one machine instruction. The parent comment sounded to me like one assembly instruction could map to s…
> There's a bit of a miscommunication going on. What I meant was, when you write an assembly instruction, that maps to one machine instruction. That's not true on x86-16, x86-32 and x86-64. For example 060o, 310o and 062o, 301o (...o means "octal"; for the reason why I give this example in octal instead of hexadecimal cf. https://news.ycombinator.com/item?id=13051770 ) both stand for "xor al, cl" (the assembler you u…
Said another way, when you write:
MOV eax, 5
This will map to _either_:
110111 _or_ 110110, but _not_ both in sequence.
Re: Learning to Read X86 Assembly Language
#189Earlier quoted context omitted.
This is about learning to read, not learning to write. If you're ever in a situation where you need to read assembly, it's typically not up to you what ISA it'll be in. There are two situations where I've had to read assembly: either reverse-engineering a compiled binary or trying to understand the compiler output for a small piece of a program I'm working on in a higher-level language.
Oh. Well then, yeah. Besides, you don't have to worry about the worst of x86 in those cases. I'm pretty sure everyone has to learn at least that much x86 at some point, like it or not.
It's a good skill to have, and since not everyone has it you will often be able to solve problems that no one else can.
Re: Learning to Read X86 Assembly Language
#190Earlier quoted context omitted.
It helps to have actual real life experience under your belt when making such claims. You seem to be parroting what countless rants have already repeated without much content.
The GP didn't have much content either, merely listing off other obsessively backwards compatible things. Your reply might be suitable in a formal debate setting (as would "fallacy!" claims be suitable when challenging faulty deductive logic) but this isn't a debate, it's a conversation. The source of one's claims doesn't matter, you only know they're probably not from experience because the Parent was kind enough to…
I coded my first assembler program (a link relocation routine) when I was 13, so age is pretty meaningless in the context of assembler coding.