Live data from Hacker News

Assembly Hall of Shame

github.com

101–110 of 118 posts

Re: Assembly Hall of Shame

#101

Using MMIO is cheating and makes the results very boring. It would be much more interesting to know the results if you're only allowed to use main memory.

I'm not sure how to properly measure DRAM access, but for register/immediate-only instructions there is https://uops.info/table.html. It does not measure x87 transcendentals (I guess because microcode results in different performance), but CPUID is a notable mention.

Re: Assembly Hall of Shame

#102
post #78

Earlier quoted context omitted.

There were several NOPs - XCHG BX,BX and so on. Those were taken later to be prefixes for new classes of opcodes.

None was. XCHG AX,AX is special because XCHG AX,reg has a one-byte encoding. You're probably confusing with: - POP CS being broken and later becoming a prefix - some opcodes being "reserved NOPs", i.e. reserved without generating #UD. They are used for instructions that may be defined in the future while guaranteeing backwards compatibility, for example new kinds of prefetches. MPX bounds checking instructions were a…

Was I thinking of 0x86?

Re: Assembly Hall of Shame

#104
post #78

Earlier quoted context omitted.

None was. XCHG AX,AX is special because XCHG AX,reg has a one-byte encoding. You're probably confusing with: - POP CS being broken and later becoming a prefix - some opcodes being "reserved NOPs", i.e. reserved without generating #UD. They are used for instructions that may be defined in the future while guaranteeing backwards compatibility, for example new kinds of prefetches. MPX bounds checking instructions were a…

Was I thinking of 0x86?

0x86 and 0x87 (XCHG rm,r with byte- and word-sized operands) encode nops in the same way as 0x90, but were never redefined as prefixes.

It's interesting that a lot of ALU operations occupy four opcodes (memory source/memory destination x byte/word) but 0x84/0x85 and 0x86/0x87 only need two because not only are they commutative, but also 0x84/0x85 do not write to any operands and 0x86/0x87 write to both. So there is no difference between memory as the source or destination operand.

Re: Assembly Hall of Shame

#105
post #80

Bus cycles can be arbitrarily long on any processor that has memory cycles with a hand shake requiring an ack, with no timeout. E.g. we can build a board around a MC68000 where we make it lock up forever in a bus cycle, waiting for a DTACK that doesn't arrive. Some early microprocessors had clocked bus cycles without handshaking. They would put out an address on some address lines and signal some line together with a…

Bus cycles can also be arbitrarily long on those microprocessors if they don't use dynamic logic - you can stop the clock.

> Times are normalized based on the CPU base clock frequency

Re: Assembly Hall of Shame

#106
post #28
post #13

Earlier quoted context omitted.

I remember reading once somewhere: If some app responds in 10ms or less, it is INTERACTIVE . makes you think.

It is literally impossible to respond to input in 10ms on most platforms, for various reasons. The USB input lag of 12-30ms and the 60Hz refresh rate of most monitors being just the first two.

> The USB input lag of 12-30ms

How'd you get that number? USB defaults to polling at 125Hz and a lot of devices go at 1000Hz (or higher). The rest of the pipeline should be a fraction of a millisecond. I guess bad debouncing hardware can add a lot more, but that's far from USB's fault.

Re: Assembly Hall of Shame

#107
post #91

Depending on his interpretation of the rules about trapped instructions, one could just build a loop in the x86 page tables. Those are usually a tree linked by pointers, and any page table lookup can create another page fault that creates another lookup that... Leads to x86 page table MMU magic being turing complete: https://github.com/jbangert/trapcc And the simplest thing you can do on such a system is just to loop…

Page tables are physically addressed, so can't recurse. I assume this thing actually works by causing a page fault on the first instruction of the page fault handler, which is a new instruction.

x86’s page tables’ accessed and dirty bits do something that one might be forgiven for calling “recursion”.

Re: Assembly Hall of Shame

#108
post #73
post #55

Earlier quoted context omitted.

The decoder is an implementation detail that is a subcomponent of NOP; GP was right, and your correction isn't.

As specified by the spec, it arguably increments RIP by one. The actual typical hardware implementation just fetches the next 16-32 bytes from icache, shifts it to the correct alignment, and slams it into a bunch of parallel decoders which each attempts to decode one x86 instruction per byte. The next cycle, the first 1-6 non-overlapping valid instructions are accepted into a queue for further decoding. The NOP almos…

As long as everyone is being outrageous pedantic: NOP, like all other non-faulting, non-control-transferring instructions, increments RIP by the length of the instruction, which may or may not be one. A prefixed NOP is still NOP.

Re: Assembly Hall of Shame

#109
post #75

I wonder if you can do some damage with scatter/gather ops within a VM, such that each fetch is a TLB miss inside the VM, and every table walk fetch is a TLB miss outside of the VM (which gets you up to 24 "fetches per fetch").

I believe that many (all?) x86 CPUs will cheerfully load page tables from MMIO space. And at least some of the paging formats let you set the UC memory type for page tables. (And don’t forget MTRRs.)

Re: Assembly Hall of Shame

#110

Earlier quoted context omitted.

this is also why 60 hz refresh rate is all but dead outside of console gaming (not to mention 1000hz poll rate devices being the norm)

absolutely not, try finding a 15" 4K OLED with a refresh rate other than 60Hz

there are plentiful OLEDs in 4k with refresh rates from 100Hz to 480Hz. your problem is a small size problem. 15” is targeted more towards portable work monitors, not gaming in 2026
Post reply on HN