Live data from Hacker News

Learning to Read X86 Assembly Language

patshaughnessy.net

221–230 of 238 posts

Re: Learning to Read X86 Assembly Language

#221

Earlier quoted context omitted.

Probably because you need to deal with the MMU. You can't just write raw assembly and expect it to work (ignoring the MMU), but the kernel takes care of that for you.

I am not following - what is raw assembly? I can write a complete userland program using only Assembly and it will run just fine. When do I need to deal with the MMU exactly?

> When do I need to deal with the MMU exactly?

When writing programs for user mode (ring 3 on x86), you hardly need to care (except sometimes use some segment override prefixes (cf. https://news.ycombinator.com/item?id=13052076), which pedantically is "dealing with the MMU", since because of the MMU this works; but in my opinion it is not necessary to understand the technical details behind it, why this works).

On the other hand, if you are an OS ("operating system", here I don't mean "open source") developer, you probably better know the details of the MMU.

Concerning https://news.ycombinator.com/item?id=13052892: I also consider the author's statement as misleading that one has to know how segmentation works. The knowledge of about segmentation is absolutely necessary for x86-16 (real mode), which many people tend to associate with assembly (because there seem to be many more assembly tutorials available for DOS/x86-16 than for x86-32 or even x86-64), but hardly relevent for people who just write user mode code.

Re: Learning to Read X86 Assembly Language

#222
post #175

Earlier quoted context omitted.

Bear in mind that this isn't a release build, so the generated assembly will not be optimized at all.

There isn't really much more to optimise: at higher optimization levels, the compiler will figure out whether that was a one time operation or not, and if he determines that it was, it will simply hardcode: moveq $52, %eax but all the extra cruft with stack and frame pointer setup will remain unchanged, and will still be there, if only to comply with the ABI calling conventions. I guesstimate that there are up to 50…

Most crystal programs make heavy use of inlining, at least from my experience profiling crystal programs, which removes the whole overhead entirely.

Re: Learning to Read X86 Assembly Language

#223

Earlier quoted context omitted.

I haven't done any 68K Asm and barely glanced at SPARC, but how does src, dst interact with noncommutative operations like subtraction and comparison? E.g. with x86 Intel syntax, cmp eax, 5 ; eax - 5 jg morethan5 ; eax > 5 ? then jump. sub eax, ecx ; eax = eax - ecx This is one of the most confusing things about AT&T x86 --- the comparisons and subtractions have their operands reversed, and you have to identify and m…

This is one of the most confusing things about AT&T x86 --- the comparisons and subtractions have their operands reversed, That is confusing as all hell to me: if I compare x to 5, and 5 to x, it's still the same comparison, so what difference does it make? Anyway, on Motorola 68000 it would look like so, assuming data was in data register 0 (there are eight general purpose data registers, and eight general purpose a…

>That is confusing as all hell to me: if I compare x to 5, and 5 to x, it's still the same comparison, so what difference does it make?

I haven't done assembly code for a while, and was not an expert at it earlier, so guessing, but:

it may be because of what flags in the flags register (if there is one nowadays) get set - they could be different for the two versions of your comparison.

Re: Learning to Read X86 Assembly Language

#224

Earlier quoted context omitted.

It's helpful to realize x86 assembly is not what's executed by the machine; machine code is. One assembly instruction, e.g. ADDL, is translated to several different machine code instructions depending on the destination, source, and addressing mode.

Can you point to a source for this? All x86 assemblers that I know of map one assembly instruction to one machine instruction.

>Can you point to a source for this? All x86 assemblers that I know of map one assembly instruction to one machine instruction.

Seeing the confusion and clarifications in the replies to your comment, I think it may have been more clear if you had said (and you probably meant):

"Can you point to a source for this? All x86 assemblers that I know of map one assembly instruction to one out of a set of machine instructions (where the chosen machine instruction depends on things like the addressing mode (immediate, indexed, indirect indexed, etc. - I'm using older terms for addressing mode, not sure if they are valid now with newer processors. but the concept is the same).

Re: Learning to Read X86 Assembly Language

#225
post #223

Earlier quoted context omitted.

This is one of the most confusing things about AT&T x86 --- the comparisons and subtractions have their operands reversed, That is confusing as all hell to me: if I compare x to 5, and 5 to x, it's still the same comparison, so what difference does it make? Anyway, on Motorola 68000 it would look like so, assuming data was in data register 0 (there are eight general purpose data registers, and eight general purpose a…

>That is confusing as all hell to me: if I compare x to 5, and 5 to x, it's still the same comparison, so what difference does it make? I haven't done assembly code for a while, and was not an expert at it earlier, so guessing, but: it may be because of what flags in the flags register (if there is one nowadays) get set - they could be different for the two versions of your comparison.

Yes, there is a status register, every processor must have one (or else the processor couldn't function). Doesn't matter whether you compare 5 to a register (or memory location, depending on the processor), or memory / register to 5, the same bit(s) will still be set in the status register.

Re: Learning to Read X86 Assembly Language

#226
post #222

Earlier quoted context omitted.

There isn't really much more to optimise: at higher optimization levels, the compiler will figure out whether that was a one time operation or not, and if he determines that it was, it will simply hardcode: moveq $52, %eax but all the extra cruft with stack and frame pointer setup will remain unchanged, and will still be there, if only to comply with the ABI calling conventions. I guesstimate that there are up to 50…

Most crystal programs make heavy use of inlining, at least from my experience profiling crystal programs, which removes the whole overhead entirely.

Then you end up with huge code sizes, where calls like

  jsr ScrollRaster(pc)
end up repeating the ScrollRaster code over and over and over again, basically leading to macro expansion. And depending on the processor, your code might end up being too large to fit into the instruction cache... and you just kissed instruction burst mode bye-bye. This is unlikely to be the case on modern 80x86 processors as they have staggering amounts of cache, but who knows what embedded platforms and targets people are targeting this very moment as I write this, and who knows how small the instruction and data caches might be on those.

Re: Learning to Read X86 Assembly Language

#227

Earlier quoted context omitted.

There isn't really much more to optimise: at higher optimization levels, the compiler will figure out whether that was a one time operation or not, and if he determines that it was, it will simply hardcode: moveq $52, %eax but all the extra cruft with stack and frame pointer setup will remain unchanged, and will still be there, if only to comply with the ABI calling conventions. I guesstimate that there are up to 50…

-O2 will remove stack pointer setup

You have to have stack and frame setup if the code is to be ABI / target platform's calling convention compliant. Which compiler are you referring to, because GCC won't remove it, as far as I could tell looking at the generated assembler code?

You could purposely tell GCC to omit the frame pointer -fomit-frame-pointer, but then you just made the code extremely difficult to debug (and stack setup code will still be generated, as the compiler can't generate useful / functional code without it), so that's no solution either.

Re: Learning to Read X86 Assembly Language

#228
post #223

Earlier quoted context omitted.

>That is confusing as all hell to me: if I compare x to 5, and 5 to x, it's still the same comparison, so what difference does it make? I haven't done assembly code for a while, and was not an expert at it earlier, so guessing, but: it may be because of what flags in the flags register (if there is one nowadays) get set - they could be different for the two versions of your comparison.

Yes, there is a status register, every processor must have one (or else the processor couldn't function). Doesn't matter whether you compare 5 to a register (or memory location, depending on the processor), or memory / register to 5, the same bit(s) will still be set in the status register.

>Doesn't matter whether you compare 5 to a register (or memory location, depending on the processor), or memory / register to 5, the same bit(s) will still be set in the status register.

Are you sure? That was my whole point - that it may not be that way. As I said, it's been a while, but it seems to me that the bits that get set in the flags/status register, on comparing A to B, should be, in some sense at least, the opposite (maybe not for all the bits) of what would get set on comparing B to A; because I thought it would be done by subtracting A from B or B from A, and then setting (some of) those flag bits based on which was greater or equal. If that is so, comparing A to B will not have the same result in the register as comparing B to A. And the reason why I think so, is that there are assembly instuctions like JGE (Jump if Greater or Equal), JE (Jump if Equal), JNE (Jump if Not Equal), etc. - the meaning of those instructions would get changed and so would the resulting action (jump or not jump) based on the looking at the flags set on comparing A to B vs. B to A.

Re: Learning to Read X86 Assembly Language

#229
post #222

Earlier quoted context omitted.

Most crystal programs make heavy use of inlining, at least from my experience profiling crystal programs, which removes the whole overhead entirely.

Then you end up with huge code sizes, where calls like jsr ScrollRaster(pc) end up repeating the ScrollRaster code over and over and over again, basically leading to macro expansion. And depending on the processor, your code might end up being too large to fit into the instruction cache... and you just kissed instruction burst mode bye-bye. This is unlikely to be the case on modern 80x86 processors as they have stagg…

It's LLVM's choice when it inlines, I'm sure it has some fancy heuristics.
Post reply on HN