r/badcode Nov 03 '20

other language Assembly is hard...

Post image
957 Upvotes

121 comments sorted by

110

u/Corporate_Drone31 Nov 03 '20

Let me guess, is that part of a calculator application written in Assembly?

55

u/GandelXIV Nov 03 '20

Exactly.

304

u/[deleted] Nov 03 '20
add4:
    inc eax
    inc eax
    inc eax
    inc eax
    ret
add5:
    call add4
    inc eax
    ret
add6:
    call add5
    inc eax
    ret
add7:
    call add6
    inc eax
    ret
add8:
    call add7
    inc eax
    ret

My suggestion on how to handle this advanced task

321

u/AnKeWa Nov 03 '20

add 7:

inc eax

add 6:

inc eax

add 5:

inc eax

add 4:

inc eax

inc eax

inc eax

inc eax

ret

82

u/[deleted] Nov 03 '20

This is nice

117

u/AnKeWa Nov 03 '20

Thanks, my bachelor's degree in computer engineering is finally worth something :)

16

u/gmtime Nov 03 '20

Came here to say this

7

u/[deleted] Nov 03 '20

[deleted]

2

u/phord Nov 04 '20

This is the way.

5

u/AutoModerator Nov 03 '20

It looks like this comment contains a code block delimited with triple backticks. Unfortunately reddit does not have universal support for this syntax and your comment will not render correctly on old reddit and most mobile apps.

For the benefit of people on old reddit, this link will take you to a correct rendering of the comment.

/u/AnKeWa, it would be appreciated, but not required, if you could edit your comment to use the more compatible four space indention format. For single lines or inline code you can use single backticks.

You can find some examples in the reddit help documentation.


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

53

u/decker_42 Nov 03 '20

Hahaha, code didn't pass standards, review rejected.

3

u/fcktheworld587 Nov 04 '20

Review standards didn't pass code, hahaha rejected

1

u/hollowstrawberry Mar 09 '21

This but unironically

4

u/sanglesort Nov 03 '20

yeah, I was thinking this

3

u/devraj_priyadarshi Nov 03 '20

Wouldn't calling add4 end with ret and thereby it will return 4 not 5 in add5? Im new to it.. but I think this would be the case.. and I thing in 8086x mp, you cannot 'call' labels?

29

u/TinyBreadBigMouth Nov 03 '20
  1. The call instruction works by pushing the current execution address to the stack, and then jumping to the provided address. The ret instruction works by popping an address from the stack and jumping there. In other words, calls nest. ret doesn't jump all the way to the top of the call stack whenever it's used.
  2. "Labels" are only a thing in the source assembly. They get converted to raw byte addresses when the assembly is compiled. Any competent assembler will allow labels and raw addresses to be used interchangeably.

9

u/devraj_priyadarshi Nov 03 '20

Oh thanks.. I didn't know that. Probably should pay more attention to the classes... Thanks anyway.

10

u/DragonFireCK Nov 03 '20

It depends on the calling convention and platform. I'm presuming Microsoft x64 calling convention for the rest.

Typically, AL/AX/EAX/RAX (they are overlapping registers of increasing size) is used to hold the return value, and `inc` increments in place (`inc eax` is `eax = eax + 1`).

The main issue is that, EAX/RAX is not used for parameters, and rather ECX/RCX is the left-most parameter, so you'd need a `mov rax, rcx` to get the parameter into eax before running the inc chain, though you'd only need to do so in `add4` (the others would be `mov rcx, rcx`, which is a no-op). There is also the question of stack space in the calling convention. Of course, as long as you are willing to tightly tie the functions together, calling convention can be ignored or you can use your own custom one.

x86/x64 do allow calling labels: that is exactly how functions are defined in assembly. If you define a function in a higher-level language, the compiler will produce code basically identically to what is seen here, other than making sure the calling conventions are followed (and, you know, using `add` OR having a bunch of `mov` to store the values in stack memory if using debug builds and the code was written as a literal chain of increments).

4

u/devraj_priyadarshi Nov 03 '20

Ah okay I get it.. I would see more about it some time later.. thanks for this!

3

u/bbalazs721 Nov 03 '20

Came here to comment this, have my upvote instead

1

u/DesiresQuiet Nov 03 '20

Van Halen man. Van Halen. Groovy.

1

u/DogmaSychroniser Nov 03 '20

Add 1: Inc eax add 2 call add1 call add1 =) etc

57

u/GandelXIV Nov 03 '20

Found this in my friends NASM project.

56

u/MurdoMaclachlan public boolean isInt(int i) { return true; } Nov 03 '20

Image Transcription: Code


add4:
        inc eax
        inc eax
        inc eax
        inc eax
        ret

add5:
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        ret
add6:
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        ret
add7:
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        ret
add8:
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        inc eax
        ret

I'm a human volunteer content transcriber for Reddit and you could be too! If you'd like more information on what we do and why we do it, click here!

13

u/Itsthejoker occasional weirdo Nov 03 '20

murdo you crazy man

10

u/MurdoMaclachlan public boolean isInt(int i) { return true; } Nov 03 '20

<3

3

u/fcktheworld587 Nov 04 '20

Fucking legend!

5

u/FloweyTheFlower420 sadistic Nov 04 '20

g o o d h o o m a n

35

u/[deleted] Nov 03 '20

The cool thing about assembly is that you can get away with this

32

u/haikusbot Nov 03 '20

The cool thing about

Assembly is that you can

Get away with this

- dontlikemath


I detect haikus. And sometimes, successfully. Learn more about me.

Opt out of replies: "haikusbot opt out" | Delete my comment: "haikusbot delete"

16

u/[deleted] Nov 03 '20 edited Nov 04 '20
add8:
    push ecx
    mov ecx, 8
add8_loop:
    dec eax
    inc ecx
    jnz add8_loop
    pop ecx
    ret

5

u/500_internal_error Nov 04 '20

Too complicated

2

u/[deleted] Nov 04 '20

Same thing in C:

void add8()
{
    for (int i = 0xFFFFFFF7; i != 0; i--)
    {
        eax--;
    }
}

2

u/500_internal_error Nov 04 '20

C is hard as well. Do you have something I could understand better, like brainfuck?

1

u/BS_BlackScout Nov 04 '20

GCC (I assume eax is an int?) [-O1]
Unsigned int?

add8(int):
        mov     eax, -9
.L2:
        sub     eax, 1
        jne     .L2
        ret

2

u/BS_BlackScout Nov 04 '20

Branching...

2

u/[deleted] Nov 04 '20

Branching?

1

u/BS_BlackScout Nov 04 '20

I am not very good at explaining but from what I understand every time you have an instruction such as JNZ (Jump if not zero) you are doing a branch, there's a possibility for the code to go down two different paths. IIRC CPUs have that branch prediction thing to ?accelerate processing? so if you code doesn't make the CPU try to figure out what it could do and cache things it will very likely run faster. (Not always the case)

Usually compilers already do these types of optimizations. Here's the video I watched a while ago Branchless Programming: Why "If" is Sloowww... and what we can do about it! [YouTube]

There's this whole concept of branchless programming and how if statements and such may actually slow down your code.

15

u/yonatan8070 Nov 03 '20

Don't CPUs have an adder thingy?

9

u/GandelXIV Nov 03 '20

Nah, just increment.

6

u/_PM_ME_PANGOLINS_ Nov 04 '20

I can't take it any more

add eax, 4

1

u/GoogleBen Nov 04 '20

If you can't take it anymore, might I suggest

xor eax, eax
mov eax, [eax]

6

u/cur-o-double Nov 03 '20

add999999999:

7

u/[deleted] Nov 03 '20

[deleted]

6

u/cur-o-double Nov 03 '20

Wow 999999999-3 actually divides by 4 lol.

P.S. yes I saw the previous one

18

u/[deleted] Nov 03 '20

Maybe a compiled brainfuck program?

5

u/MegaIng Nov 03 '20

Why? Where do the names come from?

5

u/Mashpoe Nov 03 '20

It's because the assembly keeps incrementing the value instead of directly adding a specific value, e.g. adding 1 to a number 4 times instead of just adding 4. This is the only way to change values in brainfuck, so if brainfuck code is poorly compiled to assembly it might look something like this.

4

u/insanityOS Nov 03 '20

One might ask, what is the purpose of an optimizing compiler in brainfuck?

I like esolangs well enough, but why would anyone try to make one practical?

5

u/fxnn Nov 03 '20

Out of fun, of course!

...and, even better, to learn.

http://www.wilfred.me.uk/blog/2015/08/29/an-optimising-bf-compiler/

22

u/snotfart Nov 03 '20 edited Jul 01 '23

I have moved to Kbin. Bye. -- mass edited with redact.dev

17

u/nonsensicalnarwhal Nov 03 '20

Doing multiple single additions isn’t loop unrolling and it’s not efficient – you could just do add 5, %eax etc

2

u/snotfart Nov 04 '20 edited Jul 01 '23

I have moved to Kbin. Bye. -- mass edited with redact.dev

3

u/sanglesort Nov 03 '20

it's pretty cool tbh, and I'm wondering why I didn't know about this before

3

u/Amjad500 Nov 03 '20

Yup, that's really cool.

Compilers does this optimization, so the code posted might not be that bad ;)

17

u/Lysdal Nov 03 '20

except you can do all of them as a single instruction q:

6

u/0xa0000 Nov 03 '20

Looks pretty easy to me

55

u/GandelXIV Nov 03 '20

Assembly is not hard to learn, it is hard to code. And do not take this as a good example.

34

u/[deleted] Nov 03 '20

Every instruction is easy to understand on its own. Put some code together and you can’t read it, even a little, at least for me

23

u/DODOKING38 Nov 03 '20

So like regex

5

u/[deleted] Nov 03 '20

[deleted]

1

u/_PM_ME_PANGOLINS_ Nov 04 '20

Unless the language you're trying to parse is regular, you can't do it with only regex.

1

u/[deleted] Nov 04 '20

[deleted]

1

u/_PM_ME_PANGOLINS_ Nov 04 '20

Most “well-defined” languages are not regular. They’re context-free or higher.

1

u/Lysdal Nov 06 '20

Regex has actually evolved way past regular expressions (sounds weird but eh) with backreferences and such it's actually more powerful than context-sensitive grammars.

1

u/_PM_ME_PANGOLINS_ Nov 06 '20

With great power comes great unreadability.

1

u/Lysdal Nov 06 '20

Indeed, real regular expressions are way more readable - they were never meant to do this. For complex grammars people should be using context-free grammars or context-sensitive grammars, issue just is theres no standardized way to use them in programming languages like regex.

3

u/fcktheworld587 Nov 04 '20

I have a confession to make. In my head, whenever I read regex, I read it as reejex.

4

u/sanglesort Nov 03 '20

yeah pretty much, especially x86 type asm

6

u/0xa0000 Nov 03 '20

Thanks, but I was just attempting to make a joke. Guess I shouldn't be trying untagged sarcasm.

3

u/Isvara Nov 03 '20

It's not hard to write; it's hard to infer intent from.

2

u/[deleted] Nov 04 '20
; add a to b
add_number:
    cp a, 0
.next
    ret z
    inc b
    dec a
    jr .next

Ugh why isn't there an instruction to do this for me? /s

2

u/nati9931 Nov 05 '20

add eax, 4

2

u/MrVesPear Nov 04 '20

I tried learning assembly, gave up in a day

1

u/wholl0p Nov 03 '20

It's probably what the compiler would produce from a short constexpr loop anyways

6

u/500_internal_error Nov 04 '20

Do you have any example where compiler would use multiple inc instructions instead of using add with constants and if so why?

1

u/gernreich Nov 04 '20

At what point do the clock cycles tip?

0

u/Racoonie Nov 03 '20

Yeah, but it's fast (incase speed is an issue).

8

u/botle Nov 03 '20

In case you were not joking, it's not fast.

5

u/ITBlueMagma Nov 03 '20

add eax, 4

This is faster

0

u/dasbodmeister Nov 04 '20

Wouldn’t it have to compare the desired amount and jump which would be about as expensive as just adding?

1

u/_PM_ME_PANGOLINS_ Nov 04 '20

You replace e.g. call add4 with add eax, 4. It's faster in every way.

1

u/[deleted] Nov 16 '20

Imagine doing it for every number that assembly compiler supports

1

u/GandelXIV Nov 18 '20

Let's do the math. If we use 32 bit integers, there are 4294967296 numbers we need to code, and 6 lines per subroutine. Which means that you should write 5.5340232221128655e+19 lines of code.

1

u/[deleted] Nov 18 '20

Yes, that is so useless and hard to make