Formatovany tisk pro 8bit
Martin Záruba
swz na volny.cz
Úterý Duben 23 18:23:30 CEST 2024
Chvíli mi to trvalo, než jsem to pochopil, ale je to jasné. Jen to
potvrzuje, jak důležité je (alespoň částečně) chápat, co je výsledkem
překladu. Logika myšlení se moc podobá buď programování na mém prvním
(sálovém) počítači EC1010, který měl trošku podobnou architekturu nebo
naopak na AT89C4051, který má sice úplně jinak koncipované instrukce,
ale ono to vlastně není tak důležité.
Spíš myslím, že podstatné je umět si představit, jak i jednoduchý kód v
C vytvoří mnoho strojových instrukcí. Skoro si netroufám představit si,
co je výsledkem, pokud bych použil float.
Martin Záruba
Dne 23.4.2024 v 17:02 Jan Waclawek napsal(a):
> Obsah +1 (mimochodom s tym alloca()/buf[l] sa uz staticka analyza aj tak
> neda robit, rovnako staci trocha volani cez smerniky a uz je to takmer
> alebo uplne nemozne); ale trocha jazykovej buzeracie: kombinacia "stack" a
> "halda" mi je proti srsti... :-)
>
> A k otazke pana kolegu Zarubu v inom maili: ano, alloca() alebo buf[l]
> zvacsia zasobnik (SP = 3E:3D; pri zapise do SP sa zakazuje prerusenie
> kvoli neatomicite toho zapisu) a sucasne si niekam odlozia smernik na ten
> vysledny pridany objekt (v tomto pripade v pare R17:R16) -- mimochodom, v
> tejto ukazje je strlen() inlineovany a na konci je inlineovana "imitovana"
> funkcia print():
>
> volatile char oc;
>
> void print(char * s) {
> while(*s != '\0') {
> oc = *s;
> s++;
> }
> }
>
> void test_a(char * s) {
> uint32_t l;
> char * buf;
>
> l = strlen(s) + 1;
> buf = alloca(l);
> strcpy(buf, s);
> print(buf);
> }
>
>
> void test_a(char * s) {
> 124: ef 92 push r14
> 126: ff 92 push r15
> 128: 0f 93 push r16
> 12a: 1f 93 push r17
> 12c: cf 93 push r28
> 12e: df 93 push r29
> 130: cd b7 in r28, 0x3d ; 61
> 132: de b7 in r29, 0x3e ; 62
> 134: dc 01 movw r26, r24
> 136: ed b6 in r14, 0x3d ; 61
> 138: fe b6 in r15, 0x3e ; 62
> uint32_t l;
> char * buf;
>
> l = strlen(s) + 1;
> 13a: fc 01 movw r30, r24
> 13c: 01 90 ld r0, Z+
> 13e: 00 20 and r0, r0
> 140: e9 f7 brne .-6 ; 0x13c <test_a+0x18>
> 142: e8 1b sub r30, r24
> 144: f9 0b sbc r31, r25
> buf = alloca(l);
> 146: 8d b7 in r24, 0x3d ; 61
> 148: 9e b7 in r25, 0x3e ; 62
> 14a: 8e 1b sub r24, r30
> 14c: 9f 0b sbc r25, r31
> 14e: 0f b6 in r0, 0x3f ; 63
> 150: f8 94 cli
> 152: 9e bf out 0x3e, r25 ; 62
> 154: 0f be out 0x3f, r0 ; 63
> 156: 8d bf out 0x3d, r24 ; 61
> 158: 0d b7 in r16, 0x3d ; 61
> 15a: 1e b7 in r17, 0x3e ; 62
> 15c: 0f 5f subi r16, 0xFF ; 255
> 15e: 1f 4f sbci r17, 0xFF ; 255
> strcpy(buf, s);
> 160: bd 01 movw r22, r26
> 162: c8 01 movw r24, r16
> 164: 0e 94 0d 01 call 0x21a ; 0x21a <strcpy>
> 168: 04 c0 rjmp .+8 ; 0x172 <test_a+0x4e>
> volatile char oc;
>
> void print(char * s) {
> while(*s != '\0') {
> oc = *s;
> 16a: 80 93 02 02 sts 0x0202, r24
> s++;
> 16e: 0f 5f subi r16, 0xFF ; 255
> 170: 1f 4f sbci r17, 0xFF ; 255
> #include <alloca.h>
>
> volatile char oc;
>
> void print(char * s) {
> while(*s != '\0') {
> 172: f8 01 movw r30, r16
> 174: 80 81 ld r24, Z
> 176: 88 23 and r24, r24
> 178: c1 f7 brne .-16 ; 0x16a <test_a+0x46>
>
> l = strlen(s) + 1;
> buf = alloca(l);
> strcpy(buf, s);
> print(buf);
> }
> 17a: 0f b6 in r0, 0x3f ; 63
> 17c: f8 94 cli
> 17e: fe be out 0x3e, r15 ; 62
> 180: 0f be out 0x3f, r0 ; 63
> 182: ed be out 0x3d, r14 ; 61
> 184: df 91 pop r29
> 186: cf 91 pop r28
> 188: 1f 91 pop r17
> 18a: 0f 91 pop r16
> 18c: ff 90 pop r15
> 18e: ef 90 pop r14
> 190: 08 95 ret
>
>
> wek
>
>
> ----- Original Message ---------------
>
>> Kompilátor velikost stacku nezná. Můľe být od pár bytů na opravdu malém
>> MCU po 4MiB na vlákno v OS. Takľe to je past, předevąím pro bare-metal a
>> C++. Můľete jednoduąe vytvořit lokální proměnnou pro objekt, který můľe
>> uvnitř obsahovat jakékoli buffery a stack přeteče. Jinak řečeno - past
>> je v tom, ľe je to jednoduché a nijak to nevaruje.
>> Sice existují nástroje na statickou analýzu stacku, ale co jsem to před
>> léty zkouąel, stejně to ukazovalo blbosti. Co se osvědčilo je popsat na
>> začátku celý stack nějakým vzorem, třeba 0xDEADBEEF, nechat program
>> běľet a pak se debugerem podívat, kde tento vzor končí, tedy je přepsán
>> programem. Předpokladem je, ľe stack je za .bss a není mezi tím halda.
>> Pokud tam halda je, lze takto zjistit i její pouľití.
>>
>> Mrazík
>>
>> On 23. 04. 24 15:12, Martin Záruba wrote:
>>> Jeątě jeden postřeh: Kompilátoru vůbec nevadí nesmyslná deklarace
>>> velikosti pole jako lokální proměnné. ...
>>>
> _______________________________________________
> HW-list mailing list - sponsored bywww.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20240423/0f5aaeca/attachment.htm>
Další informace o konferenci Hw-list