Fråga om Strängar.
- SeniorLemuren
- Inlägg: 8368
- Blev medlem: 26 maj 2009, 12:20:37
- Ort: Kristinehamn
Re: Fråga om Strängar.
Ja men meningen är ju att jag skall skriva något på displayen. Jag skickar ju inte en tom sträng för utskrift, det känns ju lite onödigt.
Re: Fråga om Strängar.
> Pascal-strängar är ju inte bättre, om du deklarerar en sträng på 10 tecken så finns det inget
> som hindrar att du skriver 40 i första byten och därmed hamnar långt utanför strängen.
Jag vet inte hur man "skriver i första byten", posta gärna ett exempel. Jag tror
normalt inte att man över huvudtaget kommer åt den, det är helt internt.
Vi kan kolla några små exempel. Först i C:
Vi har alltså sagt att vi vill ha en sträng med 5 tecken, men det är inget problem
att skriva en längre sträng, så länge som vi får det, *C* hindrar oss inte.
Men om vi försöker med att lägga ett tecken lite "längre bort" så spricker det.
Visst, vi får ett "informal message", men det går att undertrycka med en switch...
"ACCVIO", d.v.s att vi har försökt skriva där vi inte får skriva, men *försökt*.
Pascal hanterar det lite annorlunda.
Först ett exempel som är OK:
Fungerar som förväntat. Sedan med ett exempel med en för lång sträng:
Här får vi alltså ett runtime error. Den stora skillnaden är att vi inte ens *försöker*
skriva utanför strängen, Pascal hindrar oss från det.
Det är alltså Pascal runtime miljön som säger ifrån, inte OS'et i sig.
Om man har ett OS som inte har bra minnesskydd, där man t.ex kan skriva
till areaor som har exekverbar kod, så förvärras det hela. D.v.s att man inte
skulle få t.ex en ACCVIO som ovan utan det skulle krascha på ett mer
okontrollerat sätt. Eller så uppstår det en "exploit". C's perkare är en
annan källa till problem, men som sagt, så länge man bara inte kan skriva
till minnesareaor som har exekverbar kod, så är det rellativt lungt.
> För att klara sig undan såna grejer så måste man förutom att hålla reda på strängens nuvarande
längd även hålla reda på den max tillåtna, och då börjar vi får lite avancerade strängstrukturer:)
Ja, poängen är alltså att vissa språk gör det åt dig.
> som hindrar att du skriver 40 i första byten och därmed hamnar långt utanför strängen.
Jag vet inte hur man "skriver i första byten", posta gärna ett exempel. Jag tror
normalt inte att man över huvudtaget kommer åt den, det är helt internt.
Vi kan kolla några små exempel. Först i C:
Kod: Markera allt
$ type str_c.c
# include "stdio"
char *text [5];
void main()
{
*text = "ABCDEFGH\0";
printf("%s", *text);
}
$ cc str_c
$ link str_c
$ run str_c
ABCDEFGH
$
att skriva en längre sträng, så länge som vi får det, *C* hindrar oss inte.
Men om vi försöker med att lägga ett tecken lite "längre bort" så spricker det.
Visst, vi får ett "informal message", men det går att undertrycka med en switch...
Kod: Markera allt
$ type str_c.c
# include "stdio"
char *text [5];
void main()
{
text[100000] = "A";
printf("%s", *text);
}
$ cc/nowarnings str_c
$ link str_c
$ run str_c
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=0000000000091A80, PC=00000000000200C8, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
STR_C STR_C main 1608 00000000000000C8 00000000000200C8
STR_C STR_C __main 1606 0000000000000064 0000000000020064
0 FFFFFFFF8038BC44 FFFFFFFF8038BC44
%TRACE-I-END, end of TRACE stack dump
$
Pascal hanterar det lite annorlunda.
Först ett exempel som är OK:
Kod: Markera allt
$ type str_pas.pas
program str(output);
var
text : string(5);
begin
text := "ABCDE";
writeln(text);
end.
$ pas str_pas
$ link str_pas
$ run str_pas
ABCDE
$
Kod: Markera allt
$ type str_pas.pas
program str(output);
var
text : string(5);
begin
text := "ABCDEF";
writeln(text);
end.
$ pas str_pas
$ link str_pas
$ run str_pas
%PAS-F-STRASGLEN, string assignment length error
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
STR_PAS STR STR 5 00000000000000C8 00000000000200C8
0 FFFFFFFF8038BC44 FFFFFFFF8038BC44
%TRACE-I-END, end of TRACE stack dump
$
skriva utanför strängen, Pascal hindrar oss från det.
Kod: Markera allt
STRASGLEN, string assignment length error
Explanation: Your program attempted to assign to a string variable a
character string that is longer than the declared maximum length of the
variable (if the variable’s type is VARYING) or that is not of the same
length as the variable (if the variable’s type is PACKED ARRAY OF
CHAR).
User Action: Correct the program so that the string is of a correct length
for the variable to which it is being assigned
Om man har ett OS som inte har bra minnesskydd, där man t.ex kan skriva
till areaor som har exekverbar kod, så förvärras det hela. D.v.s att man inte
skulle få t.ex en ACCVIO som ovan utan det skulle krascha på ett mer
okontrollerat sätt. Eller så uppstår det en "exploit". C's perkare är en
annan källa till problem, men som sagt, så länge man bara inte kan skriva
till minnesareaor som har exekverbar kod, så är det rellativt lungt.
> För att klara sig undan såna grejer så måste man förutom att hålla reda på strängens nuvarande
längd även hålla reda på den max tillåtna, och då börjar vi får lite avancerade strängstrukturer:)
Ja, poängen är alltså att vissa språk gör det åt dig.

Re: Fråga om Strängar.
Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod, vilken sedan körs av en runtime-modul, på samma sätt som BASIC, JAVA .NET mfl.
Skillnaden är ju att C kompilerar till exekverbar kod, alltså finns det ingen runtime-modul som kan övervaka detta.
Sedan har jag en känsla av att varningar för sådana här saker är beroende på vilka verktyg man använder.
Skillnaden är ju att C kompilerar till exekverbar kod, alltså finns det ingen runtime-modul som kan övervaka detta.
Sedan har jag en känsla av att varningar för sådana här saker är beroende på vilka verktyg man använder.
Re: Fråga om Strängar.
I de Pascal dialekter jag hobbyjobbat så kommer det ut riktiga exe filer
Så om kompilatorn i Pascal hindra mig från att göra dumheter ser jag det som en bra funktion.
Så om kompilatorn i Pascal hindra mig från att göra dumheter ser jag det som en bra funktion.
Re: Fråga om Strängar.
Jo, men i sodjans exempel så är det ju inte kompilatorn som varnar, eftersom varningen kommer från en runtime-modul vid exekveringen.
(i C-fallet är det väl OSet som varnar)
(i C-fallet är det väl OSet som varnar)
- SeniorLemuren
- Inlägg: 8368
- Blev medlem: 26 maj 2009, 12:20:37
- Ort: Kristinehamn
Re: Fråga om Strängar.
Anledningen till att jag längtade efter Pascal var att jag har programmerat mer än 5000 timmar professionellt (Delphi) och aldrig behövt fundera på hur filerna hanteras internt.
Det finns verktyg för att manipulera filerna precis hur man önskar utan att behöva bekymra sig om hur detta hanteras internt. Programmen som genereras av Delphi behöver ingen runtimemodul utan fungerar självständigt.
Det finns verktyg för att manipulera filerna precis hur man önskar utan att behöva bekymra sig om hur detta hanteras internt. Programmen som genereras av Delphi behöver ingen runtimemodul utan fungerar självständigt.
Re: Fråga om Strängar.
Pascal, rent allmänt, kompilerar till exekverbar kod. Ingen skillnad mot C. Men just i Sodjans exempel så ser det ut som att den varianten av Pascal faktiskt gör så.
Re: Fråga om Strängar.
Pascal har väl i alla tider kompilerat till mellankod ala P-kod och sedan är det lite upp till kompileringsmiljön om P-koden behålls i sin helhet och sedan skarva på en runtimemaskin som läser av P-koden i 'exe'-paketet eller kompilera hela vägen till för plattformen och os-miljön passande maskinkod.
Dom flesta språks kompilatorer gör en psedokod under kompileringen och mycket av optimeringsarbetet på den högre nivån görs i det steget och senare från den optimerade mellankoden har man en optimeringsprocess på den från mellankoden genererade maskinkodsmiljön för aktuell plattform och det är då man måste optimera avseende cache-hantering, pipeline, om det det går att parallellisera, om man optimera för fart eller minnessnålhet etc.
Så det är nog ganska korrekt och jämföra med java och motsvarande med Pascal men med skillnaden att Pascal var först med mellan/psedokoden i sitt runtimepaket och var det redan på ABC80-tiden som var den miljön jag första gången stötte på Pascal
Det var där jag också lärde mig att Pascal var ett språk där man lekte och byggde hus med färdiga legobitar - inte hur man snickrade nya legobitar från grunden för att pilla på en viss adress för ett IO som inte finns i några funktionsbibliotek och hantera tidskritiska saker som att skriva en mjukvaru-UART och det som var där som gjorde att i mina ögon Pascal åkte åt sidan som användbart språk på lågnivågrottning eftersom det fans inget lågnivåstöd för att komma åt den förbaskade V24-gränssittet på ABC80 på något sätt (och som var den akuta behovet) som någon visste hur man gjorde (i ABC80-basic kunde man använda PEEK och POKE för att trycka in maskinkod och exekvera det vilket gjorde att basic var mer användbar än Pascal i det här fallet...) ... - några år senare stötte jag på språket C, vilket var mycket bättre i min smak när man skulle grotta lågnivå - dock är 'C' är i många fall att betrakta som högnivåassembler och man måste programmera lika noggrant som just att man håller på med assembler och dess resursallokering och att hålla reda på vad man gör och det är därför som C är dominerande på microcontroller och OS-språk eftersom ett OS handlar mycket om att fingra på riktigt lågnivå och många fall tidkritiskt nästan hela tiden.
C är att betrakta som en mycket vass skalpell som kan göra stordåd med en säker hand - men med osäker hand så kan det bli storslakt då denna inte har några skyddsräcken/småbarnskydd som annars skulle hindra i finliret
Redan på den tiden jag stötte på Pascal runt 1982 eller så var portabiliteten argumentet för att använda P-kod och mycket av resonemanget kändes sedan igen när Java kom och var nytt - och åter igen stötte man på bekymret hur man gjorde själva legobitarna som man sedan skulle byggde med...
Dom flesta språks kompilatorer gör en psedokod under kompileringen och mycket av optimeringsarbetet på den högre nivån görs i det steget och senare från den optimerade mellankoden har man en optimeringsprocess på den från mellankoden genererade maskinkodsmiljön för aktuell plattform och det är då man måste optimera avseende cache-hantering, pipeline, om det det går att parallellisera, om man optimera för fart eller minnessnålhet etc.
Så det är nog ganska korrekt och jämföra med java och motsvarande med Pascal men med skillnaden att Pascal var först med mellan/psedokoden i sitt runtimepaket och var det redan på ABC80-tiden som var den miljön jag första gången stötte på Pascal
Det var där jag också lärde mig att Pascal var ett språk där man lekte och byggde hus med färdiga legobitar - inte hur man snickrade nya legobitar från grunden för att pilla på en viss adress för ett IO som inte finns i några funktionsbibliotek och hantera tidskritiska saker som att skriva en mjukvaru-UART och det som var där som gjorde att i mina ögon Pascal åkte åt sidan som användbart språk på lågnivågrottning eftersom det fans inget lågnivåstöd för att komma åt den förbaskade V24-gränssittet på ABC80 på något sätt (och som var den akuta behovet) som någon visste hur man gjorde (i ABC80-basic kunde man använda PEEK och POKE för att trycka in maskinkod och exekvera det vilket gjorde att basic var mer användbar än Pascal i det här fallet...) ... - några år senare stötte jag på språket C, vilket var mycket bättre i min smak när man skulle grotta lågnivå - dock är 'C' är i många fall att betrakta som högnivåassembler och man måste programmera lika noggrant som just att man håller på med assembler och dess resursallokering och att hålla reda på vad man gör och det är därför som C är dominerande på microcontroller och OS-språk eftersom ett OS handlar mycket om att fingra på riktigt lågnivå och många fall tidkritiskt nästan hela tiden.
C är att betrakta som en mycket vass skalpell som kan göra stordåd med en säker hand - men med osäker hand så kan det bli storslakt då denna inte har några skyddsräcken/småbarnskydd som annars skulle hindra i finliret
Redan på den tiden jag stötte på Pascal runt 1982 eller så var portabiliteten argumentet för att använda P-kod och mycket av resonemanget kändes sedan igen när Java kom och var nytt - och åter igen stötte man på bekymret hur man gjorde själva legobitarna som man sedan skulle byggde med...
Re: Fråga om Strängar.
Kompilatorn jag kör är ingen P-kod variant. Det är en "vanlig" kompilator.
Det syns bl.a på att det hela länkas precis som vanligt.
Skillnaden är att Pascal-koden kollar index till arrayer eller "strängar" i runtime
och att C inte gör det. C försöker bara skriva och OS'et slår den på fingrarna
(om OS'et är smart nog att göra det!). Pascal kommer att kolla indexet *innan*
accessen mot minnet och ge ett runtime error om det är utanför gränserna.
> Jo, men i sodjans exempel så är det ju inte kompilatorn som varnar,
Nej. Men det är ju kompilatorn (och standarden för språket) som har skapat
koden som varnar, så indirekt kommer ju varningen (eller felet) p.g.a av något
som kompilatorn har skapat, så att säga.
> Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod,
Nej, det blir maskinkod direkt. Här är kompilatorlistan
Jag kan inte läsa koden rakt av, men det känns som att kollen av stränglängden görs här:
Jag har inte kollat, men det är sannolikt "-16394" som genererar det aktuella
felmeddelandet ("%PAS-F-STRASGLEN - string assignment length error").
Om jag ändrar till "text : string(7);" i koden så blir det "CMPULE R19, 7, R16" ovan
så det verkar hänga ihop.
Som sagt, poängen är i alla fall att en del språk har mer inbyggda skydd mot
att "skjuta sig i foten", så att säga. I många fall gör det även exploits som
använder "buffer overflow" svårare.
Det syns bl.a på att det hela länkas precis som vanligt.
Skillnaden är att Pascal-koden kollar index till arrayer eller "strängar" i runtime
och att C inte gör det. C försöker bara skriva och OS'et slår den på fingrarna
(om OS'et är smart nog att göra det!). Pascal kommer att kolla indexet *innan*
accessen mot minnet och ge ett runtime error om det är utanför gränserna.
> Jo, men i sodjans exempel så är det ju inte kompilatorn som varnar,
Nej. Men det är ju kompilatorn (och standarden för språket) som har skapat
koden som varnar, så indirekt kommer ju varningen (eller felet) p.g.a av något
som kompilatorn har skapat, så att säga.

> Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod,
Nej, det blir maskinkod direkt. Här är kompilatorlistan
Kod: Markera allt
$ pascal /nooptimize /list /machine_code str_pas
$
$ type STR_PAS.LIS
STR Source Code Listing 2-JAN-2014 12:13:45 HP Pascal Alpha V6.1-116 Page 1
01 2-JAN-2014 02:34:22 USER:<JANNE.STRING>STR_PAS.PAS;20
IDC-PL-SL
0 0 1 program str(output);
0 0 2 var
0 0 3 text : string(5);
0 0 4 begin
0 1 5 text := "ABCDEF";
0 1 6 writeln(text);
0 0 7 end.
STR Machine Code Listing 2-JAN-2014 12:13:45 HP Pascal Alpha V6.1-116 Page 2
01 2-JAN-2014 02:34:22 USER:<JANNE.STRING>STR_PAS.PAS;20
IDC-PL-SL
.PSECT $CODE$, OCTA, PIC, CON, REL, LCL, SHR,-
EXE, NORD, NOWRT
0000 STR:
23DEFFD0 0000 LDA SP, -48(SP)
B77E0000 0004 STQ R27, (SP)
B75E0018 0008 STQ R26, 24(SP)
B45E0020 000C STQ R2, 32(SP)
B7BE0028 0010 STQ FP, 40(SP)
63FF0000 0014 TRAPB
47FE041D 0018 MOV SP, FP
47FB0402 001C MOV R27, R2
47FE0400 0020 MOV SP, R0
47E0B401 0024 MOV 5, R1 ; 000003
B03D0010 0028 STL R1, TEXT%TYPE ; R1, 16(FP)
47E0F411 002C MOV 7, R17
B23D0014 0030 STL R17, 20(FP)
23DEFFF0 0034 LDA SP, -16(SP)
47FE0401 0038 MOV SP, R1
47FE0400 003C MOV SP, R0
B43D0008 0040 STQ R1, 8(FP)
47E0D413 0044 MOV 6, R19 ; 000005
4260B7B0 0048 CMPULE R19, 5, R16
2FFE0000 004C UNOP
E6000029 0050 BEQ R16, L$3
0054 L$2:
A61D0008 0054 LDQ R16, 8(FP)
47E0B401 0058 MOV 5, R1
42610532 005C SUBQ R19, R1, R18
46410CD3 0060 CMOVGT R18, R1, R19
F2000027 0064 BLBS R16, L$4
0068 L$5:
2C100000 0068 LDQ_U R0, (R16)
4A700372 006C INSWL R19, R16, R18
48100240 0070 MSKWL R0, R16, R0
44120400 0074 BIS R0, R18, R0
3C100000 0078 STQ_U R0, (R16)
22100002 007C LDA R16, 2(R16)
47F30411 0080 MOV R19, R17
22420040 0084 LDA R18, 64(R2)
A7420038 0088 LDQ R26, 56(R2)
2FFE0000 008C UNOP
6B5A4000 0090 JSR R26, OTS$MOVE ; R26, R26
A41D0008 0094 LDQ R0, 8(FP) ; 000006
A2200000 0098 LDL R17, (R0)
4A261731 009C SLL R17, 48, R17
4A261691 00A0 SRL R17, 48, R17
A43D0008 00A4 LDQ R1, 8(FP)
22410002 00A8 LDA R18, 2(R1)
A6020030 00AC LDQ R16, 48(R2)
47E07419 00B0 MOV 3, R25
A7420050 00B4 LDQ R26, 80(R2)
A7620058 00B8 LDQ R27, 88(R2)
2FFE0000 00BC UNOP
6B5A4000 00C0 JSR R26, PAS$WRITE_STRING ; R26, R26
A6020030 00C4 LDQ R16, 48(R2)
STR Machine Code Listing 2-JAN-2014 12:13:45 HP Pascal Alpha V6.1-116 Page 3
01 STR 2-JAN-2014 02:34:22 USER:<JANNE.STRING>STR_PAS.PAS;20
IDC-PL-SL
47E03419 00C8 MOV 1, R25
A7420060 00CC LDQ R26, 96(R2)
A7620068 00D0 LDQ R27, 104(R2)
6B5A4000 00D4 JSR R26, PAS$WRITELN2 ; R26, R26
47E03400 00D8 MOV 1, R0 ; 000007
63FF0000 00DC TRAPB
47FD041E 00E0 MOV FP, SP
A75D0018 00E4 LDQ R26, 24(FP)
A45D0020 00E8 LDQ R2, 32(FP)
A7BD0028 00EC LDQ FP, 40(FP)
23DE0030 00F0 LDA SP, 48(SP)
6BFA8001 00F4 RET R26
00F8 L$3: ; 000005
221FBFF6 00F8 MOV -16394, R16
000000AA 00FC GENTRAP
C3FFFFD4 0100 BR L$2
0104 L$4:
2C100001 0104 LDQ_U R0, 1(R16)
4A700AF2 0108 INSWH R19, R16, R18
48100A40 010C MSKWH R0, R16, R0
44120400 0110 BIS R0, R18, R0
3C100001 0114 STQ_U R0, 1(R16)
C3FFFFD3 0118 BR L$5
Routine Size: 284 bytes, Routine Base: $CODE$ + 0000
.PSECT $LINK$, OCTA, NOPIC, CON, REL, LCL,-
NOSHR, NOEXE, RD, NOWRT
0000 ; Stack-Frame invocation descriptor
Entry point: STR
Entry Length: 28
Static Handler: PAS$HANDLER2
Registers used: R0-R2, R16-R20, R25-R26, R28-FP
Registers saved: R2, FP
Fixed Stack Size: 48
00000000 ; Handler data for PAS$HANDLER2
00000000
00000000
00000000
00000000 0030 .ADDRESS PAS$FV_OUTPUT
0038 .CODE_ADDRESS OTS$MOVE
44434241 0040 .ASCII \ABCDEF\
4645 0044
0050 .LINKAGE PAS$WRITE_STRING
0060 .LINKAGE PAS$WRITELN2
Pascal Compilation Statistics 2-JAN-2014 12:13:45 HP Pascal Alpha V6.1-116 Page 4
2-JAN-2014 02:34:22 USER:<JANNE.STRING>STR_PAS.PAS;20
PSECT SUMMARY
Name Bytes Attributes
$CODE$ 284 pic, con, rel, lcl, shr, exe, nord, nowrt, align(4)
$LINK$ 112 nopic, con, rel, lcl, noshr, noexe, rd, nowrt, align(4)
COMMAND QUALIFIERS
PASCAL/NOOPTIMIZE/LIST/MACHINE_CODE STR_PAS
/ALIGN=NATURAL
/NOANALYSIS_DATA
/ARCHITECTURE=GENERIC
/ASSUME=(ACCURACY_SENSITIVE,NOBYTE_ALIGNED_POINTERS)
/CDD_QUAD_TYPE=EMPTY_RECORD
/CHECK=(BOUNDS,NOCASE_SELECTORS,DECLARATIONS,NOOVERFLOW,
NOPOINTERS,NOSUBRANGE)
/CONSTANT=NONE
/NOCROSS_REFERENCE
/DEBUG=(NOSYMBOLS,TRACEBACK)
/NODESIGN
/NODIAGNOSTICS
/ENUMERATION_SIZE=LONG
/NOENVIRONMENT
/ERROR_LIMIT=30
/FLOAT=G_FLOAT
/GRANULARITY=QUADWORD
/IDENT=01
/INCLUDE=None Specified
/LIST=USER:<JANNE.STRING>STR_PAS.LIS;17
/MACHINE
/MATH_LIBRARY=ACCURATE
/OBJECT=USER:<JANNE.STRING>STR_PAS.OBJ;25
/OPTIMIZE=(LEVEL=0,TUNE=GENERIC,INLINE=NONE)
/PEN_CHECKING_STYLE=COMPILATION_TIME
/NOPLATFORMS
/PSECT_MODEL=NOMULTILANGUAGE
/SHOW=(DICTIONARY,INCLUDE,HEADER,SOURCE,NOSTRUCTURE_LAYOUT,STATISTICS)
/NOSTANDARD
/TERMINAL=NONE
/NOTIE
/USAGE=(NOUNCERTAIN,UNINITIALIZED,NOUNUSED,VOLATILE,EMPTY_RECORDS,
PACKED_ACTUALS,UNSUPPORTED_CDD,NOPERFORMANCE,NONGRNACC,NOUNCALLABLE)
/WARNINGS
/ZERO_HEAP
Pascal Compilation Statistics 2-JAN-2014 12:13:45 HP Pascal Alpha V6.1-116 Page 5
2-JAN-2014 02:34:22 USER:<JANNE.STRING>STR_PAS.PAS;20
COMPILER INTERNAL TIMING
Phase CPU Elapsed Page I/O
seconds seconds faults count
Initialization 0.01 0.00 16 0
Source analysis 0.00 0.00 50 1
Symbol Table and IL Generation 0.00 0.00 28 0
Symbol Table Conversion 0.00 0.00 8 0
CIL Generation 0.00 0.00 18 0
CIL Fixup 0.00 0.00 0 0
Pointer type alias analysis 0.00 0.00 0 0
IL expansion 0.00 0.00 28 0
Optimization 0.00 0.00 0 0
Dominator tree construction 0.00 0.00 0 0
Loop dominator insertion 0.00 0.00 0 0
Lifetime analysis 0.00 0.00 0 0
IDEF computation 0.00 0.00 0 0
DATAFLOW computation 0.00 0.00 2 0
Loop transforms 0.00 0.00 0 0
BR loop/branch optimization 0.00 0.00 0 0
Strength reduction 0.00 0.00 0 0
Loop unroll/Loop optimization 0.00 0.00 0 0
Test replacement 0.00 0.00 0 0
Profitability determination 0.00 0.00 0 0
Profitability reordering 0.00 0.00 0 0
Use propagation 0.00 0.00 0 0
Split lifetime analysis 0.00 0.00 0 0
Base Binding 0.00 0.00 0 0
Code Generation 0.00 0.00 59 0
Context analysis 0.00 0.00 23 0
Register History 0.00 0.00 0 0
Temporary allocation 0.00 0.00 7 0
Code emission 0.00 0.00 20 0
Final 0.00 0.00 18 0
Peepholing 0.00 0.00 5 0
Final flow analysis 0.00 0.00 0 0
Object scheduling 0.00 0.00 0 0
Branch/jump resolution 0.00 0.00 7 0
Object module generation 0.00 0.00 19 0
DST generation 0.00 0.00 0 0
Listing 0.00 0.00 3 0
Compiler totals 0.03 0.12 368 25
COMPILATION STATISTICS
CPU time: 0.03 seconds
Elapsed time: 0.12 seconds
Pagefaults: 368
I/O Count: 25
Source lines: 7
14000 lines per CPU minute.
$
Kod: Markera allt
47E0D413 0044 MOV 6, R19 ; 000005
4260B7B0 0048 CMPULE R19, 5, R16
2FFE0000 004C UNOP
E6000029 0050 BEQ R16, L$3
...
...
00F8 L$3: ; 000005
221FBFF6 00F8 MOV -16394, R16
000000AA 00FC GENTRAP
C3FFFFD4 0100 BR L$28
felmeddelandet ("%PAS-F-STRASGLEN - string assignment length error").
Om jag ändrar till "text : string(7);" i koden så blir det "CMPULE R19, 7, R16" ovan
så det verkar hänga ihop.
Som sagt, poängen är i alla fall att en del språk har mer inbyggda skydd mot
att "skjuta sig i foten", så att säga. I många fall gör det även exploits som
använder "buffer overflow" svårare.
Re: Fråga om Strängar.
Men i ditt exempel använder du ju "riktiga" strängfunktioner. Det är ju fullt jämförbart med att använda strcat() i C.
C är ju ett språk på "lägre nivå" än Pascal, det går ju att gå åt andra hållet och titta på t.ex. perl (där det väl i princip är omöjligt att skriva utanför strängen, eftersom perl allokerar det utrymme som behövs automatiskt).
Hur blir det om du istället för en loop som indexerar strängen och lägger in ett tecken i taget?
C är ju ett språk på "lägre nivå" än Pascal, det går ju att gå åt andra hållet och titta på t.ex. perl (där det väl i princip är omöjligt att skriva utanför strängen, eftersom perl allokerar det utrymme som behövs automatiskt).
Hur blir det om du istället för en loop som indexerar strängen och lägger in ett tecken i taget?
Re: Fråga om Strängar.
Öh nä, det betyder bara att Pascalkompilatorn lägger in lite extrakod för att kolla att tilldelningen är giltig, har ju absolut ingenting med pseudokod öht. att göra.TomasL skrev:Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod, vilken sedan körs av en runtime-modul, på samma sätt som BASIC, JAVA .NET mfl.
Skillnaden är ju att C kompilerar till exekverbar kod, alltså finns det ingen runtime-modul som kan övervaka detta.
Sedan har jag en känsla av att varningar för sådana här saker är beroende på vilka verktyg man använder.
/johan
Re: Fråga om Strängar.
> Det är ju fullt jämförbart med att använda strcat() i C.
Ja, jag insåg att det haltar lite där.
Mitt C exempel skulle behöva justeras lite.
Men är det inte så att även strcat (och liknande) har problem
med att det kan "skriva utanför gränserna"? Kom det inte ett
antal alternativa rutiner ("safe"-någonting) får något tag sedan
som skulle göra det bättre?
Grundpoängen kvarstår dock, vissa programspråk har bättre
skydd mot skitfel än andra "by design". C är ett dåligt språk
i detta avseende (också
).
Ja, jag insåg att det haltar lite där.

Mitt C exempel skulle behöva justeras lite.
Men är det inte så att även strcat (och liknande) har problem
med att det kan "skriva utanför gränserna"? Kom det inte ett
antal alternativa rutiner ("safe"-någonting) får något tag sedan
som skulle göra det bättre?
Grundpoängen kvarstår dock, vissa programspråk har bättre
skydd mot skitfel än andra "by design". C är ett dåligt språk
i detta avseende (också

Re: Fråga om Strängar.
Nja, håller inte med. De värsta buggarna är ju inte de som får programmet att krascha, de upptäcker man ju rätt fort, det är värre med de som orsakar logiska fel och felaktiga data utan att krascha eller lämna varningar/felmeddelanden, de kan lurka kvar i åratal...sodjan skrev: Det är alltså Pascal runtime miljön som säger ifrån, inte OS'et i sig.
Om man har ett OS som inte har bra minnesskydd, där man t.ex kan skriva
till areaor som har exekverbar kod, så förvärras det hela. D.v.s att man inte
skulle få t.ex en ACCVIO som ovan utan det skulle krascha på ett mer
okontrollerat sätt. Eller så uppstår det en "exploit". C's perkare är en
annan källa till problem, men som sagt, så länge man bara inte kan skriva
till minnesareaor som har exekverbar kod, så är det rellativt lungt.
Och os:et kommer ju bara kunna fånga minnesfel när programmet skriver till minne det inte äger eller som är skyddat (readonly/executable). Men följande lilla kodsnutt visar ju en klassisk bugg som inte leder till en direkt krasch eller felmeddelande,bara att programmet inte gör som förväntat
Kod: Markera allt
{
char s[5];
char Status = 1;
strcpy(s, "abcde");
if(Status)
printf("%s", s);
return 0;
}
/johan
Re: Fråga om Strängar.
Är det scanf_s och liknande du tänker på? http://msdn.microsoft.com/en-us/library/w40768et.aspx
"Reads formatted data from the standard input stream. These versions of scanf, _scanf_l, wscanf, _wscanf_l have security enhancements"
"Reads formatted data from the standard input stream. These versions of scanf, _scanf_l, wscanf, _wscanf_l have security enhancements"
Re: Fråga om Strängar.
> Men följande lilla kodsnutt visar ju en klassisk bugg...
Exakt! Det är det jag menar.
Strcpy skriver alltså *6* tecken till s, och
det hade (t.ex) Pascal larmat för. Dock i runtime, men i alla fall...
> Och os:et kommer ju bara kunna fånga minnesfel när programmet skriver till minne det inte äger eller som är skyddat (readonly/executable).
Allt minne som den *kan* skriva till bör vara "read-only non-executable" som default
oavsett om det "ägs" av processen eller inte. Om man vill skriva "self-modifed"
kod så får man kode specifikt för det (d.v.s skapa sections som är "read/write, execute").
Exakt! Det är det jag menar.

det hade (t.ex) Pascal larmat för. Dock i runtime, men i alla fall...
> Och os:et kommer ju bara kunna fånga minnesfel när programmet skriver till minne det inte äger eller som är skyddat (readonly/executable).
Allt minne som den *kan* skriva till bör vara "read-only non-executable" som default
oavsett om det "ägs" av processen eller inte. Om man vill skriva "self-modifed"
kod så får man kode specifikt för det (d.v.s skapa sections som är "read/write, execute").