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字节大小,但到目前为止它不稳定,每个符号出现在一个单独的屏幕位置。
答案 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
假设bx
和si
具有一些可接受的值,因此0xb800:bx+si
指向当前文本视频模式使用的视频内存区域。嗯,这是可能的,但我不推荐它。
无论如何,如果仍然允许对寄存器值进行假设,则可以缩短至少4个字节。如果可以假设bx
和si
具有有用的值(参见上文),那么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 16h
(ah
= 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
希望这有帮助。