ภารกิจนั้นง่าย: เขียนโปรแกรมที่แตกต่างใน x86 (32- บิต) และ x86-64 (64- บิต) โดยใช้เฉพาะอักขระ ASCII ที่มองเห็นได้ที่พิมพ์ได้ 0x21 ... 0x7e (ไม่อนุญาตให้เว้นวรรคและเดล) ในรหัสเครื่อง .
- ไม่อนุญาตให้ประกอบแบบมีเงื่อนไข
- ไม่อนุญาตให้ใช้การเรียก API
- ไม่อนุญาตให้ใช้รหัสโหมดเคอร์เนล (แหวน 0)
- รหัสจะต้องทำงานโดยไม่ทำให้เกิดข้อยกเว้นทั้ง IA-32 และ x86-64 ใน Linux หรือใน OS ที่ได้รับการป้องกันอื่น ๆ
- การทำงานจะต้องไม่ขึ้นอยู่กับพารามิเตอร์บรรทัดคำสั่ง
- คำแนะนำทั้งหมดจะต้องเข้ารหัสในรหัสเครื่องโดยใช้เฉพาะอักขระ ASCII ในช่วง 0x21 ... 0x7e (33 ... 126 ทศนิยม) เช่น
cpuid
ไม่มีข้อ จำกัด (เป็น0f a2
) เว้นแต่คุณจะใช้รหัสแก้ไขด้วยตนเอง - รหัสไบนารีเดียวกันต้องทำงานใน x86 และ x86-64 แต่เนื่องจากส่วนหัวของไฟล์ (ELF / ELF64 / ฯลฯ ) อาจแตกต่างกันคุณอาจต้องรวบรวมและเชื่อมโยงอีกครั้ง อย่างไรก็ตามรหัสไบนารีจะต้องไม่เปลี่ยนแปลง
- โซลูชันควรทำงานกับโปรเซสเซอร์ทั้งหมดระหว่าง i386 ... Core i7 แต่ฉันสนใจในโซลูชันที่ จำกัด ยิ่งกว่า
- รหัสจะต้องสาขาใน 32-bit x86 แต่ไม่ได้อยู่ใน x86-64 หรือในทางกลับกัน แต่การใช้การกระโดดแบบมีเงื่อนไขนั้นไม่ได้เป็นข้อกำหนด ที่อยู่เป้าหมายสาขาจะต้องมีที่ว่างสำหรับรหัสบางส่วนอย่างน้อย 2 ไบต์ของพื้นที่ที่มีการกระโดดสั้น (
jmp rel8
) พอดี
คำตอบที่ชนะคือคำตอบที่ใช้ไบต์น้อยที่สุดในรหัสเครื่อง ไบต์ในส่วนหัวของไฟล์ (ตัวอย่างเช่น ELF / ELF64) จะไม่ถูกนับและไบต์ใด ๆ ของรหัสหลังสาขา (สำหรับจุดประสงค์ในการทดสอบเป็นต้น) จะไม่ถูกนับรวม
โปรดแสดงคำตอบของคุณเป็น ASCII เป็นเลขฐานสิบหกและแสดงความคิดเห็นรหัส
โซลูชันของฉัน 39 ไบต์:
ASCII: fhotfhatfhitfhutfhotfhatfhitfhut_H3<$t!
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