This is "dirty" in that it will not run but does show C heritage..Use..It's why understanding pointers is something to put a lot of effort into for C and why it can never be "safe" like (eg: Rust). No matter what the language gurus like to say, it is a glorified assembler. I got involved in a lot of debate back in usenet days on the "C" (and "C++") language groups, specifically over the notion "an array decays into a pointer". It's nonsense. What you have is (in loose assembler terms) is a label "1234" which gets loaded into an address register. It is then acted upon. Consider a label "foo". You can....so "()" and "[]" can be considered as operations to be performed upon that label (which is a pointer). In K&R C it was legal to say....and all you would get would be the compiler would create four bytes something akin to this pseudo asm code....so now "123" would become "143". This, of course, is silly. You're writing to a constant. Any modern machine would segfault. That hasn't always been the case. If the linker chose to put "L1" in writeable memory it would be valid .. or .. you're coding for an architecture which has no concept of memory protection. There are C compilers for 8bit cpus. It could be that....calls the vsync() routine at address "1234" on some retro cpu someone has yet to invent. Maybe you could persuade a 6502 C compiler with "((void (*)(void))0xfffc) ()" to call the reset vector.
Pointers are the fog of war. You'll bang your head against a wall for ages trying to understand them. One day the fog will clear and you'll forever wonder why they were ever an issue.
Code:
intmain(){ ((void (*)(void))1234) ();//JSR 1234 ((char*)1234) [0] = 99;//*1234 = 99 return 0;}
Code:
$ gcc -O0 -S -fverbose-asm dirty.c && clear && cat dirty.s
Code:
.arch armv8-a.file"dirty.c"// GNU C17 (Debian 12.2.0-14) version 12.2.0 (aarch64-linux-gnu)//compiled by GNU C version 12.2.0, GMP version 6.2.1, MPFR version 4.1.1-p1, MPC version 1.3.1, isl version isl-0.25-GMP// warning: MPFR header version 4.1.1-p1 differs from library version 4.2.0.// GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072// options passed: -mlittle-endian -mabi=lp64 -O0 -fasynchronous-unwind-tables.text.align2.globalmain.typemain, %functionmain:.LFB0:.cfi_startprocstpx29, x30, [sp, -16]!//,,,.cfi_def_cfa_offset 16.cfi_offset 29, -16.cfi_offset 30, -8movx29, sp//,// dirty.c:4: ((void (*)(void))1234) ();movx0, 1234// tmp95,blrx0// tmp95// dirty.c:5: ((char*)1234) [0] = 99;movx0, 1234// _1,// dirty.c:5: ((char*)1234) [0] = 99;movw1, 99// tmp96,strbw1, [x0]// tmp96, *_1// dirty.c:6: return 0;movw0, 0// _5,// dirty.c:7: }ldpx29, x30, [sp], 16//,,,.cfi_restore 30.cfi_restore 29.cfi_def_cfa_offset 0ret.cfi_endproc.LFE0:.sizemain, .-main.ident"GCC: (Debian 12.2.0-14) 12.2.0".section.note.GNU-stack,"",@progbits
Code:
foo ()//call itfoo []//access it
Code:
"123"[1]='4';
Code:
L1:.byte: 49 50 51 0//ascii "123" +nulmove L1 -> a0//runtime value of label L1 into address register a0move #1 -> X//an index registermove.b #52 -> [a0,X]//write '4' to byte at a0+X
Code:
((void (*)(void))1234) ()
Pointers are the fog of war. You'll bang your head against a wall for ages trying to understand them. One day the fog will clear and you'll forever wonder why they were ever an issue.
Statistics: Posted by swampdog — Wed Sep 11, 2024 6:39 pm