Live data from Hacker News

X86 assembly doesn’t have to be scary

blog.benjojo.co.uk

81–90 of 129 posts

Re: X86 assembly doesn’t have to be scary

#81

Earlier quoted context omitted.

> Well, the fact that we were able to abstract it out into an ISA, and still make progress would indicate that it isn't holding us back! Just because something works doesn't mean it works well. Imagine if x86-64 ditched the variety of non-32/64-bit modes. Would x86 be able to better compete with ARM in power consumption?

Not really, those use a microscopic amount of area on a modern die and shouldn't have much power impact at all when they aren't being used. You could probably change the ISA in various ways to save power, or make other uarch or arch changes - but cutting out say the 16-bit modes isn't really one of them.

> You could probably change the ISA in various ways to save power, or make other uarch or arch changes - but cutting out say the 16-bit modes isn't really one of them.

I've got no idea (obviously) but it seems that maintaining compatibility with legacy hardware shouldn't be all that cheap. If it is, kudos to Intel.

Re: X86 assembly doesn’t have to be scary

#82

Earlier quoted context omitted.

> I wonder if the history of x86 is holding us back in a big way. It started out being close to the metal but now it's an abstraction that can mislead you if you think processors are literally working the way x86 assembly describes. But when you compare high-end cores, you always see the same picture, regardless of ISA. Large surface area (~1/3 of the core) used for insn fetch/decode/schedule; they look all the same,…

>"What we do know is outside some niches (like DSPs, where VLIW reigns king)" Interesting, why is VLIW is so predominant in DPS chips?

Because VLIW is a great idea but we only know how to compile DSP code effectively for it, that being a subset of general-purpose code

Re: X86 assembly doesn’t have to be scary

#83

Earlier quoted context omitted.

Not really, those use a microscopic amount of area on a modern die and shouldn't have much power impact at all when they aren't being used. You could probably change the ISA in various ways to save power, or make other uarch or arch changes - but cutting out say the 16-bit modes isn't really one of them.

> You could probably change the ISA in various ways to save power, or make other uarch or arch changes - but cutting out say the 16-bit modes isn't really one of them. I've got no idea (obviously) but it seems that maintaining compatibility with legacy hardware shouldn't be all that cheap. If it is, kudos to Intel.

There was some point when it wasn't necessarily cheap: when chips had transistor counts in the hundreds of thousands or single digit millions. But current chips generally have billions of transistors (or at least high triple digit millions). There are just a huge number of gates to go around, and since the complexity of 16-bit support remains largely constant it becomes an ever-shrinking piece of the die.

These backwards compatibility modes don't need to be super fast (after all, current chips are perhaps 1000x the speed of the old 16-bit chips), so they don't need to get a ton of gates thrown at them: they just need to work.

If there were no backwards compatibility concerns, I'm sure Intel and AMD could like to get rid of this stuff: not so much because it uses a lot of space, but just because the design and validation effort to make sure these old ISAs keep working is probably considerable.

It's the same kind of situation with all the old effectively obsolete instructions: supporting them takes minimal space, especially when they are allowed to be slow. The encoding space they take up is more of a problem - but that can't be changed now...

Re: X86 assembly doesn’t have to be scary

#84
The problem I keep running into is that everybody's asm is different looking, and not even internally consistent. Trying to parse all of this stuff:

    [BITS 16]  ;tell the assembler that its a 16 bit code
Okay, so this is an instruction to the assembler saying that we're only working with 16 bit registers and to emit 16 bit code. Straightforwards enough here.

    [ORG 0x7C00];Origin, tell the assembler that where the code will
    

            ;be in memory after it is been loaded
This means that the first instruction will be at physical address 0x7c00 when the code loads, right? What's the first instruction, the one below?

    mov ah, 0x0A ; Set the call type for the BIOS


    mov al, 66   ; Letter to display


    mov cx, 3    ; Times to print it


    mov bh, 0    ; Page number
Makes enough sense, just mov instructions al refers to the top 8 bits of register ax and al refers to the bottom 8 bits. I see that register bh is zeroed, but what about bl? Why not xor bx, bx or something like that? Don't instructions normally go in a section named .text? How does the BIOS know where to find this code and begin execution in the first place?

...

    TIMES 510 - ($ - $$) db 0    ;fill the rest of sector with 0
Wtf is that? What's a sector? What the syntax here? Are we repeating this 510 times, or 510 minus some value? The db command is for writing bytes, but where are the bytes written to?

    DW 0xAA55          ; add boot signature at the end of bootloader
Where are these bytes written? Why is DW capitalized here when db was left in lowercase before?

Re: X86 assembly doesn’t have to be scary

#85
post #20

When I was about 14 I was enthralled with programming my new Commodore 64, first in BASIC, then 6510 assembly. I had the opportunity to accompany my mother to a one-day class on programming. Being just an intro on the subject, I was well ahead of what they would be discussing, but thought it would interesting to talk to some adults that were also into programming. I was talking to a couple of guys about what I had be…

It's funny how you can just adapt and work with whatever is available, and that becomes your norm. Especially when you don't even realize there are other options out there. Another example of this, also quite relevant to the article, is the 64K address space of a 16-bit segment; to anyone who is used to HLLs, 64-bit address spaces, and gigabytes of RAM, it seems impossibly small. Even more so when you take a modern C…

Hello world in real mode is leveraging a bunch of code and data from the BIOS, so it's not quite as small as you're suggesting, but yes, bloat is the cost in general purpose abstractions.

Smart linking is related to GC. Not all the conditional and indirect edges in the control flow graph can be skipped by the linker's graph traversal, so you usually end up with lots and lots of unused code. And then there's all the sledgehammers being used on peanuts, just because they're there, like xpath to retrieve config values.

Re: X86 assembly doesn’t have to be scary

#86
post #11

I wonder if the history of x86 is holding us back in a big way. It started out being close to the metal but now it's an abstraction that can mislead you if you think processors are literally working the way x86 assembly describes. And surely the whole spectre issue could be lessened if we could be less reliant on CPUs having to guess what to keep in cache, which code paths are most likely, etc?

Nope.

x86 decode to micro-ops is a trivial amount of die. It is constant (not completely true but true enough for all useful purposes) while transistor count has gone through many doublings. In some cases x86 is a slight win, as it can function as a form of instruction compression, slightly reducing i-cache pressure.

There may be architectural limitations (like strong store ordering) that are relevant but in practice it hasn't made a huge difference.

Re: X86 assembly doesn’t have to be scary

#87
post #11

I wonder if the history of x86 is holding us back in a big way. It started out being close to the metal but now it's an abstraction that can mislead you if you think processors are literally working the way x86 assembly describes. And surely the whole spectre issue could be lessened if we could be less reliant on CPUs having to guess what to keep in cache, which code paths are most likely, etc?

there was at least one non-realized research project where the cache was exposed as part of the architecture to be managed by the compiler (ppc lets you do some of that). i think thats a potentially very fruitful approach, but would it have helped the spectre situation in any way? oh, what you're suggesting in an analog for compiler driven speculation? that may have helped, and is also probably worth thinking about

Every single CPU architecture that has decided to lean on "smart compilers" has failed. Intel flushed billions down the drain on Itanium. They lit $100 bills on fire trying to make a smart compiler. It never paid off. Think about that for a minute.

No matter how good your compiler I'll put my money on using hardware to solve Spectre.

In the future I'd expect caches to gain some kind of exclusive tagging or set-aside a per-core reorder area. Fetches will have to go there until the instruction that performed the fetch is retired successfully, then the entry can be made visible. Other threads or cores won't observe any changes to cache state based on speculative execution. It will be complicated, cost some transistors, and have a minor but measurable performance impact.

The perf impact being having to fetch the same memory address multiple times, possibly all the way from RAM, because the instruction that fetched it before you hasn't retired yet. I don't know what impact that will have on cache traffic. If we're all very lucky, it won't be possible to use L3/L2 as side channels and we can ignore them (we probably aren't that lucky).

Re: X86 assembly doesn’t have to be scary

#88
post #10

I think to many programmers assembly is the "GOTO" of programming languanges: From the day you start learning to program, you are told that all this fancy high-level-language stuff is there so you do not have to deal with assembly. So most people never go there. I did go there, briefly, about ten years ago. It was wicked fun. But all in all, I may have written maybe 20 or 30 instructions of assembly in total. I did t…

When I hobby-program, I use assembly. I find it extremely relaxing; doing most things in assembly requires attention and concentration, so it's like solving a puzzle or like physically building something; I don't think you go into 'problem solving' mode very much, so maybe it's a break from that.

Higher level languages let you skip most of the 'menial' work of laying out the code, so your brain power gets spent a pretty different way. I like each. Obviously some languages are better suited to certain tasks.

I don't have a point; I'm just sharing what sprang to mind when I read your comment.

I will say that for something like C, having some experience with assembly makes it a lot easier to get a feel for pointers, the stack. I genuinely think everybody should try it at least once; it's just enjoyable talking almost-directly to the machine.

Re: X86 assembly doesn’t have to be scary

#90

The problem I keep running into is that everybody's asm is different looking, and not even internally consistent. Trying to parse all of this stuff: [BITS 16] ;tell the assembler that its a 16 bit code Okay, so this is an instruction to the assembler saying that we're only working with 16 bit registers and to emit 16 bit code. Straightforwards enough here. [ORG 0x7C00];Origin, tell the assembler that where the code w…

ORG shifts all addresses below it to given offset. That means that external loading code is supposed to put it there, otherwise all non-relative instructions will load/store at wrong locations.

BL is not set because it is irrelevant. How you clear/save a register was up to you. https://en.wikipedia.org/wiki/INT_10H

.text is a section of executable format, but what you got is a boot loader. It doesn’t have sections, it’s just a first 512-byte boot disk sector that is loaded at 7C00h by BIOS and directly jmp’d into.

I forgot what exactly $-$$ is, but one of those is “current” address and another should be ORG address, but I’m not sure, so this expression turns into e.g. TIMES 410 DB 0, if 100 bytes used by so far.

AA55 is a boot sector end marker, something like canary value. Never looked into that in detail.

Assemblers were mostly case-insensitive, like Pascal and BASIC. Case is up to you, if you have any preference.

Post reply on HN