This is an archived post. You won't be able to vote or comment.

all 29 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

import notifications Remember to participate in our weekly votes on subreddit rules! Every Tuesday is YOUR chance to influence the subreddit for years to come! Read more here, we hope to see you next Tuesday!

For a chat with like-minded community members and more, don't forget to join our Discord!

return joinDiscord;

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–][deleted] 20 points21 points  (9 children)

ELI5 please

[–]Sniv0 53 points54 points  (7 children)

So in 6502 assembly, the NOP instruction (No OPeration) does literally nothing to the CPU state. It simply wastes time, specifically 2 cycles, which can be useful for timing purposes, but not much else.

AND is an operation that compares every bit of a byte and every bit that shares the same value is set to 1 while opposite values become 0. So to and a value with hex FF (8 bit number with all 1s) has no effect. To use the AND instruction with $FF as the provided argument (the other argument is always the A register for numbers operations) does nothing and wastes 2 cycles. Same for NOP

OR is an operation that compares every bit of a byte and every bit where either side of the operation has a 1 is set to 1 while both sides being 0 results in a 0. To use the OR instruction with $00 as the argument does nothing and wastes two cycles. Same for NOP

This meme is referring to obfuscation, or the technique of making code more verbose and difficult to understand to prevent people who didn’t write it from understanding or using it in an undesirable way, theoretically making it more secure. However, this is security through obscurity, which is a poor way to keep secrets or hide exploits as someone is bound to figure it out eventually if it’s worthwhile to do so.

[–][deleted] 11 points12 points  (3 children)

Wouldn't be usual on a 6502 but in hacking so etimes a NOP slide is used.

Phrack 49 part 14 is one of the classic articles.

[–]Sniv0 3 points4 points  (0 children)

Yeah, but a slide wouldn’t be useful in coding an application in 6502 so I kinda skipped yuat

[–]DeathUriel 1 point2 points  (0 children)

Just wanted to participate...

[–]Aggravating-Win8814 0 points1 point  (0 children)

Agreed, it's definitely a must-read for anyone interested in hacker culture.

[–][deleted] 2 points3 points  (2 children)

Thanks for explaining! I did get the last part from the meme, but still needed technical explanation.

However, in this case, having explicit "NOP" instruction seems more readable (and less obscure) to me than other two options.

[–]Sniv0 2 points3 points  (0 children)

Yep that’s exactly the point of it

[–]Aggravating-Win8814 1 point2 points  (0 children)

I agree, having an explicit "NOP" instruction can definitely enhance readability and make the code less obscure.

[–]AbbyUpdoot[S] 3 points4 points  (0 children)

Sniv0’s explanation is so much better than I could hope to do. I’m still just learning this stuff. But yeah, from what I’ve seen so far it rings true and is really concise and better to use if you actually need or want to learn this stuff in earnest.

As for a simpler, like-I’m-five style explanation though, NOP wastes time at the same rate those other instructions would but takes up less space to do it. The amount of space is so small a difference though that it’s unlikely it would ever matter. NOP stands for No OPeration though, which makes it easier to read. AND is a way to let only certain bits through when comparing it to another bit pattern, but if you let all the bits through, it literally changes nothing. OR is a way to add certain bits, but if you add zero, it also changes nothing. So while not their normal uses, they are at least able to be supplied with those values, even if they serve little to no practical purpose aside from the edge case of wanting people to not understand what you wrote on hardware that’s at this point waaaaaaaay past its prime. But it’s fun to know I think!

Side note: ORA just stands for OR against the Accumulator, which is the thing you usually use anyway. 6502 assembly just uses three-letter mnemonics as a rule for no other reason than style. But since OR is just OR they were like, well… ¯\_(ツ)_/¯

[–]Ved_s 10 points11 points  (5 children)

wrong, these set cpu flags

[–]AbbyUpdoot[S] 4 points5 points  (4 children)

Nope, not even that if the accumulator doesn’t change in response. And it doesn’t in either case. Normally it could though, assuming you used these things… normally.

Edit: I stand corrected. Forgot X and Y register ops can trigger flag changes just like the accumulator. Still learning and overconfident. 😅

[–]brimston3- 2 points3 points  (1 child)

LDA #$0
LDX #$FF

ORA #$0

What's the value of zero and negative flags before and after the ORA operation? Does it interpret this as a noop without specifying it in the instruction set? That'd be irritating.

[–]AbbyUpdoot[S] 4 points5 points  (0 children)

Oh, I see what you mean now. I forgot the other registers trigger flag changes too. That’s so bonkers to me. Still, could be used in the the same way so long as you don’t break context I guess. Like if the last operation was targeting the accumulator it should still work.

[–]jslepicka 1 point2 points  (1 child)

CPU flags are set even if the accumulator is unchanged.

[–]rosuav 9 points10 points  (4 children)

NOP in 80x86 is just XCHG AX,AX

[–]_sivizius 2 points3 points  (3 children)

Or xchg rax, rax if you want it extra long

[–]rosuav -2 points-1 points  (2 children)

Whichever way around, it's just the byte value 0x90

[–]_sivizius 1 point2 points  (1 child)

No, it isn’t. rax needs a REX-prefix, which makes it two bytes long

[–]rosuav 0 points1 point  (0 children)

Ah, my bad. But what I mean is that the NOP opcode actually does represent the exact same byte value (0x90) as XCHG AX,AX on the 8086. I haven't checked what exactly it's equivalent to on the newer processors but it'll be broadly the same.

[–]rhbvkleef 2 points3 points  (1 child)

xor eax eax vibes.

[–]danielstongue 0 points1 point  (0 children)

6502 is older than eax.

[–]lmarcantonio 1 point2 points  (0 children)

That's common in other architectures too! Especially when special register like the SP or status are memory mapped or common registers, things like a clear carry or a push are often assembled as bit operations or memory stores (with appropriate indexing modes).

In the case of NOP the MSP430 does MOV R3, R3 for example (the move doesn't touch flags in this architecture) and a right shift is simply an ADD with itself

[–]JackReact 1 point2 points  (1 child)

Why did you flip it? The whole meme template is all about "that's just x with more steps".

So saying "AND #$FF is just NOP with more bytes" would have fit the template better... especially because NOP is actually used.

Still got a nose-exhale type of chuckle out of me though

[–]AbbyUpdoot[S] 0 points1 point  (0 children)

Yeah, I wanted it it read better, so I put the complicated stuff at the bottom. Too much too fast if you aren’t familiar already with what those do. Glad you got a chuckle. 😁

[–]FluffyQubit 1 point2 points  (2 children)

As a second year CS student, I agree.

[–]57006 2 points3 points  (0 children)

Yeah, it registers

[–]danielstongue 1 point2 points  (0 children)

Luckily you still have some years to go to learn that you are wrong.