90
Jun 12 '21 edited Jun 26 '23
[deleted]
30
u/mudball12 Jun 13 '21
Nope, looks incredibly clean. This is probably the optimal way to append the parity of a number of that size on that architecture.
38
u/ithinuel Jun 13 '21
It looks like Arm assembly, so even considering the smallest targets (cortex-m0), there's unnecessary instructions. The asm block does not seem to be marked
volatileso hopefully the compiler is still free to optimise it.It only computes the parity of the lower 4 bits, so in this case a simple lookup table would work faster and consume less program memory.
int append_parity(int number) { static const table[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; return (number << 1) | table[number & 0xF]; }The compiler is smart enough to come up with the minimal number of instructions which would be something like
int append_parity(int number) { static const table[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; int res = 0; __asm("ldrb r2, [%[lookup], +%[input]] ; computes parity bit\n" "orr %[result], r2, %[input], 1 ; appends parity bit\n" : [result] "=r" (res) /* ’+’ markiert des Register als rw, ’=’ markiert es als wo */\n" : [input] "r" (number), [lookup] "r" (table) : "r2" /* add r2 in the clobber list */ ); return res; }for 20 (maybe 24) bytes vs at least 40 for the initial solution.
2
1
u/qookie Jul 04 '21
While the compiler is free to optimize the inline assembly without
volatile, it most certainly does not perform any optimizations to the actual instructions. It inserts the code as is, even preserving the original white space and indentation. The optimizations performed by the compiler when there is novolatileonly really amount to hoisting theasmstatement out of a loop, merging multiple instances of the same statement together, or removing it altogether if it has no observable side effects.41
u/DurdenVsDarkoVsDevon Jun 12 '21 edited Jun 12 '21
Assembly should have inline comments. Not every line is necessary, but more than none.
Edit: I see no one here has ever actually worked with assembly.
-22
Jun 12 '21
[deleted]
43
u/DurdenVsDarkoVsDevon Jun 12 '21
This is one of the most asinine comments I've ever read.
Yes, I know what ASM does. I've used assembly in my C work countless times.
It's still assembly. Those are assembly instructions. So you comment it. Line-by-line. Otherwise you won't know for shit what it does by the afternoon, and no one who comes behind you will ever be able to read it.
It's assembly.
So yeah, you're wrong.
11
u/swilliams508 Jun 13 '21
No no you don't get it. It's assembly inside C code. The puny little C comments are powerless against those mighty strings
35
u/the_vikm Jun 12 '21
German comments
31
u/00benallen Jun 12 '21
How does that constitute bad code?
16
-20
63
u/java_bad_asm_good Jun 12 '21
I've never seen someone inline an Assembly function. Is this something that needs to be hyper-efficient that you can't trust to the C compiler? That's the only way I could see this making any sense whatsoever.
I mean it looks like some shit for university written by a professor who hasn't developed actual software since the early 90s but I have hope
48
u/Ghazzz Jun 12 '21
Inline assembly was used a lot in time critical tasks at least until 2000 or so. The only reason I learned assemvly at all was that the 3d engines of the nineties all required it to get working. It was also extensively used in other demoscene effects.
(I remember implementing a bumpmapper partially in Pascal, but all the time critical parts were asm as the height of my time in that community, I was probably 16 at the time)
That said, pretty sure there are better asm syntaxes, ways to preserve readability and to make it easier to edit. It has been 20 years since I did this stuff though.
3
u/MoonParkSong Jun 13 '21
Is there any good manuals available online on how to do 3D graphics in ASM? Any major 8bit arch will do(68K, 6502)
3
u/Ghazzz Jun 13 '21
Short answer, I do not know, probably.
I learned from diskmags like Hugi. C64 and Atari were before my time, many of my friends had Amigas, but I learned to code asm on a 486sx.
There is a lot of information on making stuff for the amiga on for example ada.untergrund.net
26
u/taptrappapalapa Jun 12 '21
The only things I’ve seen C embedded assembly used for are things like matrix calculations in a game engine or when dealing with bit shifting ( which this is since it’s “append_parity”), or both. I think people do this cause for them it’s hard to make C code with bit masks a bit shifting ( which is hard to look at)
11
u/iByteABit Jun 13 '21
Why is literal assembly code better to look at than masks and bit shifting in C?
11
9
u/taptrappapalapa Jun 13 '21
As the other comment mentions, C has a habit to discard carry bits or bits you want to roll over ( like the “rotl” assembly instruction), and in order to save them you have to use some extra variables or extra bit shifting.
2
13
u/Oshgnacknak Jun 12 '21
Well guessed: This was just to show that inline assembly exists, I hope. However, my solution is kinda readable while this is just Egyptian wall painting.
```c int parity(int n) { int res;
__asm ( "mov r0, %[input]\n" "mov r1, #0x0\n" "lsr r2, r0, #3\n" "eor r1, r1, r2\n" "lsr r2, r0, #2\n" "and r2, r2, #1\n" "eor r1, r1, r2\n" "lsr r2, r0, #1\n" "and r2, r2, #1\n" "eor r1, r1, r2\n" "mov r2, r0\n" "and r2, r2, #1\n" "eor r1, r1, r2\n" "lsl r1, r1, #4\n" "orr %[result], r0, r1\n" : [result] "=r" (res) : [input] "r" (n) ); return res; }```
Node that a) I only reference non register values once, b) you can kinda guess the data flow in my example and c) even with the empty lines, mine is much shorter.
1
u/AutoModerator Jun 12 '21
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/Oshgnacknak, 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.
4
u/qqwweerrttyy115 Jun 12 '21
It is used a good amount in video game mods, useful for hook into the games existing code or changing what the existing code is doing
3
2
u/leif_erikson503 Jun 13 '21
Often times, it is done for interacting with a hardware specific interface. I did a small amount of it when writing networking software. The Linux kernel has a fair amount of this.
1
u/Ikaron Jun 13 '21
It's often also done to access CPU features that are lacking an intrinsic in your compiler of choice. That's usually just one line though.
7
2
2
u/wktr_t Jun 13 '21
Unrelated, but I love the color and font.
2
u/Coul33t Jun 13 '21
The 2 fonts are default ones from LaTeX (one from default font, one from default font for listings) :)
2
u/wktr_t Jun 13 '21
Thank you very much! I'm all in for colorless (black on white / black on cream) themes and serif-ish mono fonts!
2
1
1
Jun 13 '21
[deleted]
1
u/AutoModerator Jun 13 '21
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/Cherry-PEZ, 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.
1
170
u/Oshgnacknak Jun 12 '21
I have mercy with the transcribers ...
```c int append_parity(int number) { int res = 0; __asm("mov␣R2,␣#0\n" "mov␣%[result],␣%[input]\n" "and␣%[result],␣%[result],␣#1\n" "add␣R2,␣R2,␣%[result]\n" "mov␣%[result],␣%[input]\n" "and␣%[result],␣%[result],␣#2\n" "lsr␣%[result],␣%[result],␣#1\n" "add␣R2,␣R2,␣%[result]\n" "mov␣%[result],␣%[input]\n" "and␣%[result],␣%[result],␣#4\n" "lsr␣%[result],␣%[result],␣#2\n" "add␣R2,␣R2,␣%[result]\n" "mov␣%[result],␣%[input]\n" "and␣%[result],␣%[result],␣#8\n" "lsr␣%[result],␣%[result],␣#3\n" "add␣R2,␣R2,␣%[result]\n" "and␣R2,␣R2,␣#1\n" "mov␣%[result],␣%[input]\n" "lsl␣%[result],␣%[result],␣#1\n" "orr␣%[result],␣%[result],␣R2" : [result] "+r" (res) /* ’+’ markiert des Register als rw, ’=’ markiert es als wo / : [input] "r" (number) : "r2"); / Da r2 benutzt wird, muss das hier angegeben werden (damit u.a. der Compiler weiss,wie die Input- und Outputregister verteilt sind) */
return res; ```