タスクは簡単です:マシンコードで印刷可能な可視ASCII文字0x21 ... 0x7e(スペースとdelは使用できません)のみを使用して、x86(32ビット)とx86-64(64ビット)で異なる分岐を行うプログラムを記述します。
- 条件付きアセンブリは許可されていません。
- API呼び出しの使用は許可されていません。
- カーネルモード(リング0)コードの使用は許可されていません。
- LinuxのIA-32とx86-64の両方、または他の保護モードOSで例外を発生させずにコードを実行する必要があります。
- 機能はコマンドラインパラメータに依存してはいけません。
- すべての命令は、0x21 ... 0x7e(10進数で33 ... 126)の範囲のASCII文字のみを使用してマシンコードでエンコードする必要があります。例えば 自己修正コードを使用しない限り
cpuid
、制限外です(0f a2
)。 - 同じバイナリコードをx86とx86-64で実行する必要がありますが、ファイルヘッダー(ELF / ELF64 / etc。)が異なる場合があるため、再度アセンブルしてリンクする必要があります。ただし、バイナリコードは変更しないでください。
- ソリューションはi386 ... Core i7の間のすべてのプロセッサで動作するはずですが、より限定的なソリューションにも興味があります。
- コードは32ビットx86で分岐する必要がありますが、x86-64で分岐することはできませんが、条件付きジャンプの使用は必須ではありません(間接ジャンプまたは呼び出しも受け入れられます)。分岐ターゲットアドレスは、コード用のスペース、つまりショートジャンプ(
jmp rel8
)が収まる少なくとも2バイトのスペースがあるようにする必要があります。
勝利の答えは、マシンコードの中で最も少ないバイトを使用するものです。ファイルヘッダーのバイト(ELF / ELF64など)はカウントされず、分岐後のコードのバイト(テスト目的など)もカウントされません。
回答をASCII、16進バイト、コメントコードとして提示してください。
私のソリューション、39バイト:
ASCII: fhotfhatfhitfhutfhotfhatfhitfhut_H3<$t!
16進数:66 68 6F 74 66 68 61 74 66 68 69 74 66 68 75 74 66 68 6F 74 66 68 61 74 66 68 69 74 66 68 75 74 5F 48 33 3C 24 74 21
。
コード:
; can be compiled eg. with yasm.
; yasm & ld:
; yasm -f elf64 -m amd64 -g dwarf2 x86_x86_64_branch.asm -o x86_x86_64_branch.o; ld x86_x86_64_branch.o -o x86_x86_64_branch
; yasm & gcc:
; yasm -f elf64 -m amd64 -g dwarf2 x86_x86_64_branch.asm -o x86_x86_64_branch.o; gcc -o x86_x86_64_branch x86_x86_64_branch.o
section .text
global main
extern printf
main:
push word 0x746f ; 66 68 6f 74 (x86, x86-64)
push word 0x7461 ; 66 68 61 74 (x86, x86-64)
push word 0x7469 ; 66 68 69 74 (x86, x86-64)
push word 0x7475 ; 66 68 75 74 (x86, x86-64)
push word 0x746f ; 66 68 6f 74 (x86, x86-64)
push word 0x7461 ; 66 68 61 74 (x86, x86-64)
push word 0x7469 ; 66 68 69 74 (x86, x86-64)
push word 0x7475 ; 66 68 75 74 (x86, x86-64)
db 0x5f ; x86: pop edi
; x86-64: pop rdi
db 0x48, 0x33, 0x3c, 0x24
; x86:
; 48 dec eax
; 33 3c 24 xor edi,[esp]
; x86-64:
; 48 33 3c 24 xor rdi,[rsp]
jz @bits_64 ; 0x74 0x21
; branch only if running in 64-bit mode.
; the code golf part ends here, 39 bytes so far.
; the rest is for testing only, and does not affect the answer.
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
jmp @bits_32
@bits_64:
db 0x55 ; push rbp
db 0x48, 0x89, 0xe5 ; mov rbp,rsp
db 0x48, 0x8d, 0x3c, 0x25 ; lea rdi,
dd printf_msg ; [printf_msg]
xor eax,eax
mov esi,64
call printf
db 0x5d ; pop rbp
NR_exit equ 60
xor edi,edi
mov eax,NR_exit ; number of syscall (60)
syscall
@bits_32:
lea edi,[printf_msg]
mov esi,32
call printf
mov eax,NR_exit
int 0x80
section .data
printf_msg: db "running in %d-bit system", 0x0a, 0