diff --git a/src/avr.c b/src/avr.c
index d6e78bb5..9d2bf503 100644
--- a/src/avr.c
+++ b/src/avr.c
@@ -282,6 +282,16 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 int avr_mem_hiaddr(AVRMEM * mem)
 {
   int i, n;
+  static int disableffopt;
+
+  /* calling once with NULL disables any future trailing-0xff optimisation */
+  if(!mem) {
+    disableffopt = 1;
+    return 0;
+  }
+
+  if(disableffopt)
+    return mem->size;
 
   /* return the highest non-0xff address regardless of how much
      memory was read */
diff --git a/src/fileio.c b/src/fileio.c
index 7c021ce4..429a200e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1594,7 +1594,10 @@ int fileio(int op, char * filename, FILEFMT format,
        * if we are reading flash, just mark the size as being the
        * highest non-0xff byte
        */
-      rc = avr_mem_hiaddr(mem);
+      int hiaddr = avr_mem_hiaddr(mem);
+
+      if(hiaddr < rc)           /* if trailing-0xff not disabled */
+        rc = hiaddr;
     }
   }
   if (format != FMT_IMM && !using_stdio) {
diff --git a/src/main.c b/src/main.c
index 253c6e51..c3bc0381 100644
--- a/src/main.c
+++ b/src/main.c
@@ -528,6 +528,7 @@ int main(int argc, char * argv [])
 
       case 'D': /* disable auto erase */
         uflags &= ~UF_AUTO_ERASE;
+        avr_mem_hiaddr(NULL); /* disable trailing 0xff optimisation */
         break;
 
       case 'e': /* perform a chip erase */