问题
B8 00 B8 8E E8 B4 00 CD 16 65 88 00 EF F2
The program initially had 16 bytes, but I decided, to sacrifice 2 bytes in favor of unstable input position. Here is the previous version (0 0 position):
65 88 06 00 00
Then the possible candidate was:
EF F2 ->
C3 ->
CF..CB..CC..CE
Those one-byters were also no-helpers. My faint thought is to change (not use) the segment component. Remove 65 and use default data segment. Unfortunately it seems it doesn't work.
What I'm doing wrong? Yesterday I decreased my module to 13 byte size, though it was unstable so far that every symbol appeared in a separate screen position.
回答1:
Well, it's clearly 16-bit real mode x86 code, a .com file for DOS or other flat binary.
$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
It supposes that bx
and si
have some acceptable values, so that 0xb800:bx+si
points to the video memory region that's used by the current text video mode. Well, it's possible, but I wouldn't recommend it.
Anyway, it can be made at least 4 bytes shorter, if assumptions on register values are still allowed. If it can be assumed that bx
and si
have useful values (see above), then di
probably too, so that 0xb800:di
points to the video memory region that's used by the current text video mode.
00000000 B800B8 mov ax,0xb800
00000003 8EC0 mov es,ax
00000005 98 cbw
00000006 CD16 int 0x16
00000008 AA stosb
00000009 C3 ret
First set ax
to 0xb800
and store the it to es
(the segment address of several BIOS text video modes).
Then convert the byte al
(0) to word ax
, extending the sign bit of al
to ax
, resulting in ax
= 0.
Then read input from keyboard (and wait for input, if necessary) with BIOS keyboard interrupt int 16h
(ah
= 0). ASCII code in al
, scan code in ah
.
Finally store the ASCII code to video memory (to [es:di]
) with stosb
to print the character on screen, and return to DOS (or whatever OS) with ret
.
Edit: Actually it is possible to drop the size to 12 bytes and still have a stable output address, with something like this:
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
Hope this helps.
来源:https://stackoverflow.com/questions/14243738/decreasing-the-size-of-see-what-you-type-program