2

我很好奇这是否以前做过,不一定是否具有实用价值(尽管空间效率的提高是显而易见的)。是否曾经在同一机器代码中编码多个指令?例如:

(这完全是编造的)

0xAEA2 -> 添加 R3 0xA2

0xEAE6 -> 移动 R1 0xE6

0xAAAA ...

通过向左移动一个半字节来重新解释机器代码变成:

0xEA2E -> 移动 R1 0x2E

0xAE5A -> 添加 R3 0x5A

4

3 回答 3

4

在 Smalltalk 78(所有现代 Smalltalk 方言的前身之一)的实现中,有一个双字节存储参数 0字节码,其第二个字节是加载参数 0。以这种方式,跳转到存储指令开头的代码执行存储,而跳转到它的中间(!)导致加载。您可以在Reviving Smalltalk-78 - Bert Freudenberg - IWST 2014 - 大约30 分钟-中了解更多信息

于 2014-12-19T17:05:41.950 回答
1

这并不新鲜。几年前,我们曾经举办过小型代码优化比赛。例如,下面的代码仅用 42 个字节实现了 C 函数strcpy、、strncpystpcpy。我在 1993 年写了这个。16 位 8086 汇编语言,C 可调用,在堆栈上传递参数,调用者清理堆栈。

请注意,入口点strcpy只是指令的第一个字节,它将接下来的两个字节加载到 AX 寄存器中。而db 3Ch是另一条指令的第一个字节,它消耗下一个字节(or al),然后执行由 执行的STC指令的第二个字节的or al,0F9h指令strncpy

创建一个列表文件以获取操作码,然后跟踪三个入口点中的每一个点发生的情况是很有指导意义的。

当我们修补现有代码时,这些技巧会派上用场。有时我们可以在不更改任何关键部分的地址的情况下为 .COM 文件制作二进制补丁。当我们有必须是 16 字节(或更大)对齐的东西时,这一点很重要,而且我们不想浪费 15 字节的死空间,只是为了添加另一条指令。哦,当你只有 64 K 字节可用时你会玩的游戏。

   Ideal
   Model Small,c
   CodeSeg

   Public strcpy,strncpy,stpcpy
 ;
 ; 42 bytes

 ;
 ; char * strcpy (char *dest, char *src);
 ;
 strcpy:
   db 0B8h       ;mov ax,immed
 ;
 ; char * stpcpy (char *dest, char *src);
 ;
 stpcpy:
   mov al,0Ch    ;0Ch is the opcode for OR AL,immediate
   mov cx,0ffffh ;make max count
   db 3Ch        ;cmp al,immediate
                 ;stpcpy  - CF set, ZF set
                 ;strcpy  - CF set, ZF clear
 ;
 ; char * strncpy (char *dest, char *src, unsigned len);
 ;
 strncpy:
   or al,0F9h    ;strncpy - CF clear, ZF clear
                 ;0F9h is the opcode for STC,
                 ;which is executed by strcpy and stpcpy
   pop dx        ;return address in DX
   pop bx        ;dest string in BX
   pop ax        ;source string in AX
   jc l0         ;if strncpy
   pop cx        ;then get length in CX
   push cx       ;and fixup stack
 l0:
   push ax       ;more stack fixup
   push bx       ;save return value
   push si       ;gotta save SI
   xchg si,ax    ;SI points to source string
   lahf          ;save flags for exit processing
 l1:
   lodsb         ;get character
 l2:
   jcxz Done     ;done if count = 0
   mov [bx],al   ;store character
   inc bx        ;bump dest
   or al,al      ;if character is 0 or
   loopnz l1     ;if at end of count, then done
   sahf          ;restore flags
   ja l2         ;for strncpy(), must loop until count reached
 Done:
   pop si        ;restore SI
   pop ax        ;return value in AX
   jnz AllDone   ;done if not stpcpy
   xchg ax,bx    ;otherwise return pointer to
   dec ax        ;end of string
 AllDone:
   call dx       ;return to caller

 End

我记得我花了几个小时想出那个只是为了打败我的一个朋友,他总是在这些比赛中击败我。他花了几分钟查看它并从中刮出另一个字节。

于 2014-12-20T15:37:10.350 回答
1

Redcode 初学者指南,1.22 版,版权所有 1997-2004 Ilmari Karonen:

...

Core War(或Core Wars)是一种编程游戏,其中汇编程序试图在模拟计算机的内存中相互摧毁。这些程序(或勇士)是用一种叫做Redcode的特殊语言编写的,并由一个叫做MARSMemory Array Redcode Simulator)的程序运行......

这个游戏的乐趣在于通过类似于你的“移动nibbles”的操作修改机器代码后重新解释机器代码。

有关更多信息,请参见http://www.corewars.org/information.html ...

于 2014-12-19T19:31:35.577 回答