减少看你是什么类型的程序的大小

时间:2013-01-09 18:12:16

标签: assembly x86 size hex byte

B8 00 B8 8E E8 B4 00 CD 16 65 88 00 EF F2

该程序最初有16个字节,但我决定,牺牲2个字节来支持不稳定的输入位置。这是以前的版本(0 0位置):

65 88 06 00 00

然后可能的候选人是:

EF F2 -> 
C3 ->
CF..CB..CC..CE

那些一个人也没有帮手。 我的微弱想法是改变(不使用)分段组件。删除65并使用默认数据段。不幸的是它似乎不起作用。

我做错了什么?昨天我将模块减小到13字节大小,但到目前为止它不稳定,每个符号出现在一个单独的屏幕位置。

1 个答案:

答案 0 :(得分:0)

嗯,它显然是16位实模式x86代码,DOS或其他平面二进制文件的.com文件。

$echo 'B8 00 B8 8E E8 B4 00 CD 16 65 88 00 C3' | udcli -x -16

0000000000000000 b800b8           mov ax, 0xb800          
0000000000000003 8ee8             mov gs, ax              
0000000000000005 b400             mov ah, 0x0             
0000000000000007 cd16             int 0x16                
0000000000000009 658800           mov [gs:bx+si], al      
000000000000000c c3               ret

假设bxsi具有一些可接受的值,因此0xb800:bx+si指向当前文本视频模式使用的视频内存区域。嗯,这是可能的,但我不推荐它。

无论如何,如果仍然允许对寄存器值进行假设,则可以缩短至少4个字节。如果可以假设bxsi具有有用的值(参见上文),那么di可能也是如此,以便0xb800:di指向所使用的视频内存区域当前的文字视频模式。

00000000  B800B8            mov ax,0xb800
00000003  8EC0              mov es,ax
00000005  98                cbw
00000006  CD16              int 0x16
00000008  AA                stosb
00000009  C3                ret

首先将ax设置为0xb800并将其存储到es(多个BIOS文本视频模式的段地址)。

然后将字节al(0)转换为字ax,将al的符号位扩展为ax,从而导致ax = 0。

然后使用BIOS键盘中断int 16hah = 0)从键盘读取输入(并在必要时等待输入)。 al中的ASCII代码,扫描ah中的代码。

最后用[es:di]将ASCII代码存储到视频内存(到stosb)以在屏幕上打印字符,然后使用ret返回DOS(或任何操作系统)。

编辑:实际上可以将大小减小到12个字节并且仍然有一个稳定的输出地址,如下所示:

00000000  6800B8            push word 0xb800
00000003  1F                pop ds
00000004  31C0              xor ax,ax
00000006  CD16              int 0x16
00000008  A20000            mov [0x0],al
0000000B  C3                ret

希望这有帮助。