flat assembler
Message board for the users of flat assembler.
Index
> DOS > BYTEFIX -- change a hex byte in a binary file |
Author |
|
rugxulo 10 Mar 2017, 20:39
rugxulo wrote:
Code: --- bytefix.old 2017-03-07 14:13:52 -0600 +++ bytefix.new 2017-03-10 12:19:20 -0600 @@ -40,3 +40,3 @@ DOS - mov b[errlvl],255 + neg b[errlvl] jmp Fino @@ -48,4 +48,3 @@ Fino: - mov ah,GOODBYE - mov al,b[errlvl] + mov ax,w[errlvl] DOS @@ -109,2 +108,5 @@ call getbytes +.issame: + cmp al,[di-2] + jz .ret .open: @@ -161,6 +163,7 @@ mov si,BYTE1 + mov di,oldbyte call hexbyte - mov [oldbyte],al - call hexbyte - mov [newbyte],al + stosb + call hexbyte ; newbyte + stosb ret @@ -206,12 +209,8 @@ push ax cx - mov ax,w[ofs] - mov dx,w[ofs+2] mov cl,4 .shift: - rcl ax,1 - rcl dx,1 + rcl w[ofs],1 + rcl w[ofs+2],1 loop .shift pop cx - mov w[ofs],ax - mov w[ofs+2],dx .add: @@ -261,7 +260,3 @@ - neg bh - clc - lahf - or ah,bh - sahf + shr bh,1 @@ -292,3 +287,3 @@ -errlvl db 1 +errlvl db 1, GOODBYE handle dw 0 |
|||
10 Mar 2017, 20:39 |
|
rugxulo 16 Mar 2017, 03:13
Made a (very) few fixes and improvements. Is it worth keeping the original version (and/or diff)? Meh, but for now, for completeness, I'll leave 'em "as is".
Code: ; BYTEFIX.ASM -- change a hex byte in a binary file ; ; rugxulo _AT_ gmail ; ; public domain, free for any use, nenies proprajho, "Christus Rex!" ARGC=80h ARGV=81h BYTE1=ARGV+1+8+1 CR=13 FILENAME=ARGV+1+8+1+2+1+2+1 LF=10 MINARGC=15+1 CLOSEFILE=3Eh GOODBYE=4Ch OPENFILERW=3D02h READFILE=3Fh SEEKSETFILE=4200h WRITEFILE=40h WRITESTR=9 DOS equ int 21h b equ byte w equ word macro proc name { if used name name: } endp fix end if ; section .text org 100h Main: call fixargs cmp b[ARGC],MINARGC jae .okay mov ah,WRITESTR mov dx,usagemsg DOS neg [errlvl] jmp Fino .okay: mov si,ARGV+1 call scanofs jc Fino call fixbyte Fino: mov ax,w[errlvl] DOS ; end Main proc fixargs xor ch,ch mov cl,b[ARGC] jcxz .ret push cx call stripblanks pop cx mov si,ARGV+1 mov di,si .loop: lodsb push cx mov bx,'az' push bx call rangecheck pop cx sbb bl,bl or bl,not ' ' and al,bl stosb loop .loop .ret: ret endp proc stripblanks mov di,ARGV lea si,[di+1] inc cx mov al,' ' rep scasb dec di mov b[ARGC],cl xchg si,di push cx cx rep movsb pop cx di add di,ARGV mov al,' ' std rep scasb cld inc cx mov b[di+2],0 ; NUL (for ASCIIZ filename) mov b[ARGC],cl ret endp proc fixbyte cmp b[BYTE1],'?' jz .open call getbytes jc .ret .issame: cmp al,[di-2] jz .ret .open: mov ax,OPENFILERW mov dx,FILENAME DOS jc .ret mov [handle],ax .seek: call seekbyte jc .close .read: mov ah,READFILE mov bx,[handle] mov cx,1 mov dx,foundbyte DOS jc .close .query: cmp b[BYTE1],'?' jnz .compare mov al,[foundbyte] mov [errlvl],al jmp .close .compare: mov al,[foundbyte] cmp al,b[oldbyte] jnz .close call seekbyte .write: mov ah,WRITEFILE mov bx,[handle] mov cx,1 mov dx,newbyte DOS jc .close dec [errlvl] .close: mov ah,CLOSEFILE mov bx,[handle] DOS .ret: ret endp proc seekbyte mov ax,SEEKSETFILE mov bx,[handle] mov cx,w[ofs+2] mov dx,w[ofs] DOS ret endp proc getbytes mov si,BYTE1 mov di,oldbyte call hexbyte jc .ret call hexbyte ; newbyte .ret: ret endp proc hexbyte lodsb call ishex jc .ret call asc2hex mov cl,4 shl al,cl mov dl,al lodsb push dx call ishex pop dx jc .ret call asc2hex add dl,al inc si xchg ax,dx stosb .ret: ret endp proc scanofs mov cx,8 .load: lodsb push cx call ishex pop cx jc .ret push cx call asc2hex pop cx .adjust: push ax cx mov cl,4 .shift: rcl w[ofs],1 rcl w[ofs+2],1 loop .shift pop cx .add: pop ax xor ah,ah add w[ofs],ax adc w[ofs+2],0 .continue: loop .load .ret: ret endp proc asc2hex cmp al,40h adc al,69h daa mov ah,al and al,15 mov cl,4 shr ah,cl aad ret endp proc ishex mov cx,'09' push cx call rangecheck sbb bh,bh ; mov cx,'af' ; push cx ; call rangecheck ; sbb bl,bl ; and bh,bl mov cx,'AF' push cx call rangecheck sbb bl,bl and bh,bl shr bh,1 ret ; return CF if not valid hex char endp proc rangecheck ; in: (upper_limit shl 8) + lower_limit pop bp pop dx ; mov dx,[sp+2] push bp .check: cmp al,dl sbb ch,ch inc dh cmp al,dh cmc sbb dl,dl or dl,ch cmp dl,1 ; set CF if DL == 0 cmc ; return NC if AL within valid range ret endp ; section .data errlvl db 1, GOODBYE handle dw 0 ofs dd 0 usagemsg db CR,LF,'Usage: bytefix.com CaFe5150 Ed A1 file.dat',CR,LF,'$' ; section .bss oldbyte rb 1 newbyte rb 1 foundbyte rb 1 ; EOF |
|||
16 Mar 2017, 03:13 |
|
rugxulo 10 Aug 2017, 00:52
Here's another improvement ... but I'm not too confident about it. Despite some light testing, I'm worried about bugs. Also, it's hitting the 512-byte limit, which was my goal to stay under. At this point I'm considering rewriting (again) in Turbo Pascal (hey, 4 kb output isn't too bloated, heheh).
Code: ; BYTEFIX.ASM -- change a hex byte in a binary file ; ; rugxulo _AT_ gmail ; ; public domain, free for any use, nenies proprajho, "Christus Rex!" ARGC=80h ARGV=81h BYTE1=ARGV+1+8+1 CR=13 FILENAME=ARGV+1+8+1+2+1+2+1 LF=10 MINARGC=15+1 CLOSEFILE=3Eh GOODBYE=4Ch OPENFILERW=3D02h READFILE=3Fh SEEKSETFILE=4200h WRITEFILE=40h WRITESTR=9 DOS equ int 21h b equ byte w equ word macro proc name { if used name name: } end fix end if macro endp { .ret: ret end } macro charargs { push w[BYTE1+3] push w[BYTE1] mov di,charbyte1 rept 2 \{ pop ax stosw \} } macro stripblanks { mov di,ARGV lea si,[di+1] inc cx mov al,' ' rep scasb dec di mov [ARGC],cl xchg si,di push cx cx rep movsb pop cx di add di,ARGV mov al,' ' std rep scasb cld inc cx mov b[di+2],0 ; NUL (for ASCIIZ filename) mov [ARGC],cl } macro fixargs { local .loop,.bye xor ch,ch mov cl,[ARGC] jcxz .bye push cx stripblanks pop cx mov si,ARGV+1 mov di,si .loop: lodsb push cx mov bx,'az' push bx call rangecheck pop cx sbb bl,bl or bl,not ' ' and al,bl stosb loop .loop .bye: } macro scanofs { local .load,.adjust,.shift,.add,.continue,.bye mov cx,8 .load: lodsb push cx call ishex pop cx jc .bye push cx call asc2hex pop cx .adjust: push ax cx mov cl,4 .shift: rcl w[ofs],1 rcl w[ofs+2],1 loop .shift pop cx .add: pop ax xor ah,ah add w[ofs],ax adc w[ofs+2],0 .continue: loop .load .bye: } ; -------------------------------------------------------------------- ; section .text org 100h Main: charargs fixargs cmp b[ARGC],MINARGC jae .okay mov ah,WRITESTR mov dx,usagemsg DOS neg [errlvl] jmp Fino .okay: mov si,ARGV+1 scanofs jc Fino call fixbyte Fino: mov ax,w[errlvl] DOS ; end Main ; -------------------------------------------------------------------- proc fixbyte cmp b[BYTE1],'?' jz .open call getbytes jc .ret .issame: mov al,[oldbyte] cmp al,[newbyte] jz .ret .open: mov ax,OPENFILERW mov dx,FILENAME DOS jc .ret mov [handle],ax .seek: call seekbyte jc .close .read: mov ah,READFILE mov bx,[handle] mov cx,1 mov dx,foundbyte DOS jc .close .query: cmp b[BYTE1],'?' jnz .compare mov al,[foundbyte] mov [errlvl],al jmp .close .compare: cmp b[BYTE1],'!' jz .seekagain .noforce: mov al,[foundbyte] cmp al,[oldbyte] jnz .close .seekagain: call seekbyte .write: mov ah,WRITEFILE mov bx,[handle] mov cx,1 mov dx,newbyte DOS jc .close dec [errlvl] .close: mov ah,CLOSEFILE mov bx,[handle] DOS endp proc seekbyte mov ax,SEEKSETFILE mov bx,[handle] mov cx,w[ofs+2] mov dx,w[ofs] DOS endp proc getbytes push ax mov di,oldbyte push di mov ax,[charbyte1] mov cx,[charbyte2] xchg al,ch cmp cx,'''''' jnz .hex mov cx,2 .check: xchg ah,al mov dx,'!~' push dx call rangecheck jc .bye loop .check xchg ah,al stosw jmp .bye .hex: mov si,BYTE1 cmp b[si],'!' jnz .noforce add si,3 inc di jmp .byte2 .noforce: call hexbyte jc .bye .byte2: call hexbyte ; newbyte .bye: pop di ax endp proc hexbyte lodsb call ishex jc .ret call asc2hex mov cl,4 shl al,cl mov dl,al lodsb push dx call ishex pop dx jc .ret call asc2hex add dl,al inc si xchg ax,dx stosb endp proc asc2hex cmp al,40h adc al,69h daa mov ah,al and al,15 mov cl,4 shr ah,cl aad endp proc ishex mov cx,'09' push cx call rangecheck sbb bh,bh ; mov cx,'af' ; push cx ; call rangecheck ; sbb bl,bl ; and bh,bl mov cx,'AF' push cx call rangecheck sbb bl,bl and bh,bl shr bh,1 ; return CF if not valid hex char endp proc rangecheck ; in: (upper_limit shl 8) + lower_limit pop bp pop dx ; mov dx,[sp+2] push bp .check: cmp al,dl sbb ch,ch inc dh cmp al,dh cmc sbb dl,dl or dl,ch cmp dl,1 ; set CF if DL == 0 cmc ; return NC if AL within valid range endp ; -------------------------------------------------------------------- ; section .data errlvl db 1, GOODBYE ofs dd 0 usagemsg db CR,LF,'Usage: BYTEFIX CaFe5150 Ed A1 my.dat',CR,LF,'$' ; -------------------------------------------------------------------- ; -------------------------------------------------------------------- ; section .bss oldbyte rb 1 newbyte rb 1 foundbyte rb 1 charbyte1 rw 1 charbyte2 rw 1 handle rw 1 ; -------------------------------------------------------------------- ; EOF |
|||
10 Aug 2017, 00:52 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.