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