<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p><font face="Arial">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é.</font></p>
<p><font face="Arial">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.<br>
</font></p>
<pre class="moz-signature" cols="72">Martin Záruba</pre>
<div class="moz-cite-prefix">Dne 23.4.2024 v 17:02 Jan Waclawek
napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:PC195202404231702070884dc95303b@wekPC">
<pre class="moz-quote-pre" wrap="">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 ---------------
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">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:
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">Jeątě jeden postřeh: Kompilátoru vůbec nevadí nesmyslná deklarace
velikosti pole jako lokální proměnné. ...
</pre>
</blockquote>
</blockquote>
<pre class="moz-quote-pre" wrap="">
_______________________________________________
HW-list mailing list - sponsored by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a>
<a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a>
<a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a>
</pre>
</blockquote>
</body>
</html>