Kirjoittaja: jalski
Kirjoitettu: 23.08.2012 – 17.07.2014
Tagit: ohjelmointitavat, teksti, koodi näytille, vinkki
Välillä ongelmakohtaa etsiessä voi olla hyödyllistä tutkia tiedoston sisältöä tarkemmin. Verkosta voi tietysti ladata hienon heksaeditorin, mutta tarkoitukseen monesti riittävän heksadumpin tulostavan ohjelman kirjoittaa itsekin lähes valmiin ohjelman lataukseen menevässä ajassa:
*PROCESS MARGINS(1,120) LIBS(SINGLE,STATIC); *PROCESS OPTIMIZE(2) DFT(REORDER); hexdump: proc(parms) options(main); dcl parms char(100) var; /* Union for easy character value conversion */ dcl 1 char_byte union, 2 ch char(1), 2 byte fixed bin(8) unsigned; dcl i fixed bin; dcl offs fixed bin(32) unsigned init(0); dcl buffer character(16) var; dcl in file; /* If no filename specified, give info about usage */ on undefinedfile(in) begin; put skip list ('Usage: ' || procedurename() || ' /filename'); stop; end; /* Open file for record input */ open file(in) title ('/'||parms||',type(fixed), recsize(1)') record input; /* We test the endfile condition manually, so leave empty */ on endfile(in); /* Next read and process file, one byte at a time */ read_bytes: do forever; buffer = ''; read file(in) into(ch); if endfile(in) then leave read_bytes; /* First display offset field */ put edit (trim(hex(offs)), ':') (a(8), a(2)); /* After offset field, display hex values as */ /* four groups of four bytes. Also build ASCII buffer */ /* Strip control character from input */ /* and replace with dot. */ if byte > 31 & byte < 127 then buffer = buffer || ch; else buffer = buffer || '.'; put edit (trim(hex(byte))) (a(3)); do i = 2 to 4; read file(in) into(ch); if endfile(in) then leave read_bytes; /* Strip control characters from input */ /* and replace with dot. */ if byte > 31 & byte < 127 then buffer = buffer || ch; else buffer = buffer || '.'; put edit (trim(hex(byte))) (a(3)); end; put edit (' ') (a); do i = 1 to 4; read file(in) into(ch); if endfile(in) then leave read_bytes; /* Strip control characters from input */ /* and replace with dot. */ if byte > 31 & byte < 127 then buffer = buffer || ch; else buffer = buffer || '.'; put edit (trim(hex(byte))) (a(3)); end; put edit (' ') (a); do i = 1 to 4; read file(in) into(ch); if endfile(in) then leave read_bytes; /* Strip control characters from input */ /* and replace with dot. */ if byte > 31 & byte < 127 then buffer = buffer || ch; else buffer = buffer || '.'; put edit (trim(hex(byte))) (a(3)); end; put edit (' ') (a); do i = 1 to 4; read file(in) into(ch); if endfile(in) then leave read_bytes; /* Strip control characters from input */ /* and replace with dot. */ if byte > 31 & byte < 127 then buffer = buffer || ch; else buffer = buffer || '.'; put edit (trim(hex(byte))) (a(3)); end; /* Display ASCII presentation */ put edit ('|', buffer) (column(62), a(2), a); put skip; /* Update offset */ offs += 16; end; /* Endfile condition might have left some */ /* ASCII values undisplayed */ if mod(length(buffer),16) ^= 0 then put edit ('|', buffer) (column(62), a(2), a); end hexdump;
Ohjelman esimerkkitulostus omasta kooditiedostostaan (lyhennetty):
00000000: 2A 50 52 4F 43 45 53 53 20 4D 41 52 47 49 4E 53 | *PROCESS MARGINS 00000010: 28 31 2C 31 32 30 29 20 4C 49 42 53 28 53 49 4E | (1,120) LIBS(SIN 00000020: 47 4C 45 2C 53 54 41 54 49 43 29 3B 0D 0A 2A 50 | GLE,STATIC);..*P 00000030: 52 4F 43 45 53 53 20 4F 50 54 49 4D 49 5A 45 28 | ROCESS OPTIMIZE( 00000040: 32 29 20 44 46 54 28 52 45 4F 52 44 45 52 29 3B | 2) DFT(REORDER); 00000050: 0D 0A 0D 0A 0D 0A 20 68 65 78 64 75 6D 70 3A 20 | ...... hexdump: 00000060: 70 72 6F 63 28 70 61 72 6D 73 29 20 6F 70 74 69 | proc(parms) opti 00000070: 6F 6E 73 28 6D 61 69 6E 29 3B 0D 0A 20 20 20 64 | ons(main);.. d 00000080: 63 6C 20 70 61 72 6D 73 20 63 68 61 72 28 31 30 | cl parms char(10 00000090: 30 29 20 76 61 72 3B 0D 0A 0D 0A 20 20 20 2F 2A | 0) var;.... /* 000000A0: 20 55 6E 69 6F 6E 20 66 6F 72 20 65 61 73 79 20 | Union for easy 000000B0: 63 68 61 72 61 63 74 65 72 20 76 61 6C 75 65 20 | character value 000000C0: 63 6F 6E 76 65 72 73 69 6F 6E 20 20 20 20 20 20 | conversion 000000D0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2A 2F | */ .... 00000E10: 20 20 20 20 20 20 20 20 20 20 2A 2F 0D 0A 20 20 | */.. 00000E20: 20 69 66 20 6D 6F 64 28 6C 65 6E 67 74 68 28 62 | if mod(length(b 00000E30: 75 66 66 65 72 29 2C 31 36 29 20 5E 3D 20 30 20 | uffer),16) ^= 0 00000E40: 74 68 65 6E 0D 0A 20 20 20 20 20 70 75 74 20 65 | then.. put e 00000E50: 64 69 74 20 28 27 7C 27 2C 20 62 75 66 66 65 72 | dit ('|', buffer 00000E60: 29 20 28 63 6F 6C 75 6D 6E 28 36 32 29 2C 20 61 | ) (column(62), a 00000E70: 28 32 29 2C 20 61 29 3B 0D 0A 0D 0A 20 65 6E 64 | (2), a);.... end 00000E80: 20 68 65 78 64 75 6D 70 3B | hexdump;
Tuli mieleen, että 8 tavun silmukka on turhaan kopioitu, kun sen voisi myös ajaa silmukalla kaksi kertaa peräkkäin, tai voisi käyttää 16 tavun silmukkaa ja tulostaa välilyönnin if-lauseella, kun i = 8. Lisäksi kohta on endfile(in)
jää minusta vielä vähän epäselväksi: miksi rivi tarvitaan, vaikka mitään toimintoa ei aseteta?
Suomenkieliset kommentit olisivat plussaa. Julkaisen kuitenkin vinkin nyt.