Hội ngôn ngữ


20

Viết đoạn trích ngôn ngữ lắp ráp ngắn nhất có thể .

Sử dụng bất kỳ ISA nào bạn muốn, trừ khi nó có print-quinelệnh hoặc tương đương. Ví dụ bao gồm x86, MIPS, SPARC, MMIX, IBM BAL, MIX, VAX, JVM, ARM, v.v.

Bạn có thể liên kết với _printfchức năng của thư viện chuẩn C (hoặc tương đương Java với mã byte JVM) cho I / O.

Độ dài sẽ được đánh giá cả về số lượng lệnh và kích thước của phân đoạn dữ liệu. Các giải pháp phải chứa ít nhất hai hướng dẫn.

Các quine nên in mã lắp ráp , không phải mã máy lắp ráp.


3
Ôi chà, điều này nghe có vẻ khó khăn
kẻ hèn nhát vô danh

Câu trả lời:


20

Cú pháp x86 Linux, AT & T: 244

push $10
push $34
push $s
push $34
push $37
push $37
push $s
call printf
mov $0,%ebx
mov $1,%eax
int $128
s:.ascii "push $10
push $34
push $s
push $34
push $37
push $37
push $s
call printf
mov $0,%cebx
mov $1,%ceax
int $128
s:.ascii %c%s%c%c"

(Tôi đã biên dịch nó với điều này gcc -nostartfiles -lc quine.S -o quine:)


Điều đó thật đáng buồn, bây giờ :-(
Joey

1
Tôi thường nói "công cụ phù hợp cho công việc", nhưng một lần nữa, ở đây nó không cảm thấy đúng: D
JB

Dường như có nhiều quyền hơn của tôi, mặc dù ;-)
Joey

5

Hội đồng mã hóa JVM (thông qua Jasmin ) - 952 960 990

.class public Q
.super java/io/File
.method public static main([Ljava/lang/String;)V
.limit stack 9
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc ".class public Q%n.super java/io/File%n.method public static main([Ljava/lang/String;)V%n.limit stack 9%ngetstatic java/lang/System/out Ljava/io/PrintStream;%nldc %c%s%c%nldc 3%nanewarray java/lang/Object%ndup%ndup%nldc 0%nldc 34%ninvokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;%ndup_x2%naastore%nldc 2%nswap%naastore%ndup2%nswap%nldc 1%nswap%naastore%ninvokevirtual java/io/PrintStream/printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;%npop%nreturn%n.end method"
ldc 3
anewarray java/lang/Object
dup
dup
ldc 0
ldc 34
invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;
dup_x2
aastore
ldc 2
swap
aastore
dup2
swap
ldc 1
swap
aastore
invokevirtual java/io/PrintStream/printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
pop
return
.end method

Đáng buồn thay, Jasmin không cho phép nhiều thủ thuật hay như Microsoft ilasmcho phép. Nhưng JVM có tổng cộng sáudup hướng dẫn khác nhau thực hiện tất cả các loại điều thú vị. Sắp xếp lại các mục trên ngăn xếp là điều mà .NET dường như không hỗ trợ.

Trong mọi trường hợp, tôi đoán không có mục nào trong hai mục của tôi là ứng cử viên nghiêm trọng cho mã ngắn nhất nhưng tôi đoán thật khó để làm cho chúng ngắn hơn nhiều. Do đó, chỉ để hoàn thiện :-)

Phiên bản đã nhận xét với thông tin về những gì trên ngăn xếp:

.class public Q
.super java/io/File
.method public static main([Ljava/lang/String;)V
.limit stack 9
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc ".class public Q%n.super java/io/File%n.method public static main([Ljava/lang/String;)V%n.limit stack 9%ngetstatic java/lang/System/out Ljava/io/PrintStream;%nldc %c%s%c%nldc 3%nanewarray java/lang/Object%ndup%ndup%nldc 0%nldc 34%ninvokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;%ndup_x2%naastore%nldc 2%nswap%naastore%ndup2%nswap%nldc 1%nswap%naastore%ninvokevirtual java/io/PrintStream/printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;%npop%nreturn%n.end method"
ldc 3       ; stack; System.out, string, 3
anewarray java/lang/Object    ; stack: System.out, string, Object[3]
dup
dup    ; stack: System.out, string, array, array, array
ldc 0  ; stack: System.out, string, array, array, array, 0
ldc 34   ; stack: System.out, string, array, array, array, 0, 34
invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;
dup_x2   ; stack: System.out, string, array, array, 34, array, 0, 34
aastore  ; stack: System.out, string, array, array, 34
ldc 2    ; stack: System.out, string, array, array, 34, 2
swap     ; stack: System.out, string, array, array, 2, 34
aastore  ; stack: System.out, string, array
dup2     ; stack: System.out, string, array, string, array
swap     ; stack: System.out, string, array, array, string
ldc 1    ; stack: System.out, string, array, array, string, 1
swap     ; stack: System.out, string, array, array, 1, string
aastore  ; stack: System.out, string, array
invokevirtual java/io/PrintStream/printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
pop
return
.end method

Lịch sử:

  • 2011/02/07 02:09 (990) - Phiên bản làm việc đầu tiên.
  • 2011/02/07 02:11 (960) - ldcngắn hơn bipushhoặc iconst_*.
  • 2011/02/07 02:30 (952) - Ai nói tôi cần thừa kế từ java.lang.Object? Tên lớp khác ngắn hơn rất nhiều :-)

4

gas cho x86 Linux (89 byte, bảy hướng dẫn)

Về mặt kỹ thuật, đây là gian lận.

mov $4,%al
mov $1,%bl
mov $b,%ecx
mov $89,%dl
int $128
mov %bl,%al
int $128
b:.incbin"a"

Lưu trong một tệp có tên avà lắp ráp với các lệnh sau để tạo tệp thực thi có tên a.out.

as -o a.o ; ld a.o

Lệnh này .incbinbao gồm một nguyên văn tập tin tại vị trí hiện tại. Nếu bạn sử dụng điều này để bao gồm chính mã nguồn, bạn sẽ có được một câu hỏi hay.


3

Định dạng Windows .COM: 307 ký tự

Lắp ráp, sử dụng A86, đến 51 byte. Yêu cầu không có thư viện bên ngoài ngoài hàm DOS Int21 AH = 9 (ghi chuỗi vào thiết bị xuất chuẩn).

db 185
db  51
db   0
db 190
db   0
db   1
db 191
db  47
db   1
db 172
db 178
db  10
db 199
db   6
db  45
db   1
db  32
db  32
db 180
db   0
db 246
db 242
db 128
db 196
db  48
db 136
db  37
db  79
db  10
db 192
db 117
db 242
db 180
db   9
db 186
db  42
db   1
db 205
db  33
db 226
db 221
db 195
db 100
db  98
db  32
db  32
db  51
db  49
db  10
db  13
db  36

Tôi sợ tôi đếm được 357 byte. (và chương trình của bạn thực sự cho ra 408) Mặc dù vậy, việc triển khai rất hay. Bạn có thể muốn bao gồm nguồn lắp ráp không có db để người xem khác có được cái nhìn trực tiếp.
JB

@JB: Tôi không bao gồm CR \ NL. Nhìn vào nó bây giờ, tôi thực sự nên đặt dữ liệu vào một dòng db. Điều đó sẽ làm cho nó nhỏ hơn.
Skizz

3

NASM, 223 byte

%define a "%define "
%define b "db "
%define c "%deftok "
%define d "a, 97, 32, 34, a, 34, 10, a, 98, 32, 34, b, 34, 10, a, 99, 32, 34, c, 34, 10, a, 100, 32, 34, d, 34, 10, c, 101, 32, 100, 10, b, 101, 10"
%deftok e d
db e

Đánh bại câu trả lời được chấp nhận!


2

.NET CIL - 623 669 691 723 727

.assembly H{}.method void M(){.entrypoint.locals init(string)ldstr".assembly H{0}{1}.method void M(){0}.entrypoint.locals init(string)ldstr{2}{3}{2}stloc 0ldloc 0ldc.i4 4newarr object dup dup dup dup ldc.i4 0ldstr{2}{0}{2}stelem.ref ldc.i4 1ldstr{2}{1}{2}stelem.ref ldc.i4 2ldc.i4 34box char stelem.ref ldc.i4 3ldloc 0stelem.ref call void[mscorlib]System.Console::Write(string,object[])ret{1}"stloc 0ldloc 0ldc.i4 4newarr object dup dup dup dup ldc.i4 0ldstr"{"stelem.ref ldc.i4 1ldstr"}"stelem.ref ldc.i4 2ldc.i4 34box char stelem.ref ldc.i4 3ldloc 0stelem.ref call void[mscorlib]System.Console::Write(string,object[])ret}

Một dòng duy nhất, không có ngắt dòng ở cuối.

Được định dạng và nhận xét phiên bản đầu tiên (mặc dù nó không còn là một câu hỏi nữa) - không chắc là tôi đã sai lệch nhiều so với khái niệm chung:

.assembly H{}
.method void M() {
  .entrypoint
  .locals init (
    string,
    object[]
  )
  // the string
  ldstr".assembly H{0}{1}.method void M(){0}.entrypoint.locals init(string,object[])ldstr{2}{3}{2}stloc.0 ldloc.0 ldc.i4.4 newarr object stloc.1 ldloc.1 ldc.i4.0 ldstr{2}{0}{2} stelem.ref ldloc.1 ldc.i4.1 ldstr{2}{1}{2} stelem.ref ldloc.1 ldc.i4.2 ldc.i4 34 box char stelem.ref ldloc.1 ldc.i4.3 ldloc.0 stelem.ref ldloc.1 call void[mscorlib]System.Console::Write(string,object[])ret{1}"
  stloc.0   // store in first local var
  ldloc.0   // load again. Going to be the first argument to Console::Write
  ldc.i4.4 newarr object stloc.1   // create new array and store in local var
  ldloc.1 ldc.i4.0 ldstr"{" stelem.ref   // we need a literal brace
  ldloc.1 ldc.i4.1 ldstr"}" stelem.ref   // closing, too
  ldloc.1 ldc.i4.2 ldc.i4 34 box char stelem.ref   // double quote
  ldloc.1 ldc.i4.3 ldloc.0 stelem.ref   // our format string from before
  ldloc.1 // load array
  call void[mscorlib]System.Console::Write(string,object[]) // output
  ret
}

Lịch sử :

  • 2011 / 02-06 16:48 (727) - Phiên bản làm việc đầu tiên.
  • 2011 / 02-06 17:14 (723) - Tôi không cần một khoảng trắng sau một chuỗi ký tự.
  • 2011 / 02-06 17:21 (691) - dupngắn hơn viết ldloc.1mỗi lần.
  • 2011 / 02-06 17:24 (669) - Tôi không cần khoảng trắng sau bất kỳ nghĩa đen nào và những thứ như ldloc.1có thể được viết ldloc 1để biến mã thông báo cuối cùng thành chữ. Mã byte kết quả có khả năng lớn hơn, nhưng đó là về mã trình biên dịch nên tôi không quan tâm lắm :-)
  • 2011 / 02-06 17:34 (623) - Tôi không cần object[]biến cục bộ; Tôi có thể làm tất cả những điều đó trên stack trực tiếp. Tốt đẹp.

Có vẻ như bạn đã xóa đối tượng [] khỏi phiên bản chưa được định dạng, nhưng không phải là đối tượng được định dạng ...
Aurel Bílý

@Aurel: Thật vậy, như đã lưu ý, định dạng là phiên bản đầu tiên. Ý tưởng vẫn như vậy nên tôi sẽ không cập nhật lại.
Joey

2

gas cho x86 Linux, 184 176 byte

.globl main
main:movw $34,B+87
push $B
call printf
call printf
pop B
ret
.data
B:.ascii".globl main
main:movw $34,B+87
push $B
call printf
call printf
pop B
ret
.data
B:.ascii"

Xây dựng với gcc -m32 -o a.out quine.S. ( -m32Tùy chọn này nếu HĐH của bạn đã 32 bit.)

Chỉnh sửa để thêm: Nếu chúng tôi sửa đổi các quy tắc để cho phép putsđược gọi thay vì printfsau đó có thể được thực hiện trong 182 174 byte:

.globl main
main:movw $34,B+86
push $B+1
call puts
call puts
pop B
ret
.data
B:.ascii"
.globl main
main:movw $34,B+86
push $B+1
call puts
call puts
pop B
ret
.data
B:.ascii"

(Lưu ý rằng cái này, không giống như cái trước, có một dòng mới kết thúc.)


Tôi đánh giá cao sự ngắn gọn. Nhưng tôi cảm thấy bị lừa bởi thực tế là ngoài printf / put, bạn thực sự phụ thuộc vào prolog / epilog C tiêu chuẩn, không được phép rõ ràng. Và IMHO không có nghĩa là; nhưng tôi đã có câu trả lời hàng đầu: rõ ràng là tôi thiên vị :-)
JB

Chà, người ta có thể lập luận rằng việc sử dụng C prolog / epilog hoàn toàn được phép, do đề cập đến việc sử dụng printf (). Các hàm libc không luôn luôn hoạt động một cách đáng tin cậy nếu bạn bỏ qua C prolog / epilog. Trên thực tế trên hệ thống của tôi, phiên bản của bạn không hoạt động nếu tôi chuyển đầu ra thành một tệp, vì thiết bị xuất chuẩn chỉ bị xóa trong mã C epilog. (Thay vào đó, chúng tôi đã sử dụng write (), chỉ là một trình bao bọc xung quanh một tòa nhà, nó sẽ hoạt động theo cách nào đó.)
Breadbox

Bây giờ đã khá lâu rồi, nhưng dường như tôi nhớ lại các chức năng C được phép là một điều ngạc nhiên đối với tôi lúc đó: nó đã làm cho vấn đề nghe có vẻ không trong sạch. OP đã không xuất hiện trong một thời gian dài; bây giờ sẽ khó để yêu cầu làm rõ.
JB

Lưu ý rằng ABI cho phép ghi printflại các đối số của nó trên ngăn xếp. Về mặt kỹ thuật, nó không an toàn khi chỉ calllặp lại và mong đợi các đối số tương tự, nhưng nó hoạt động trên thực tế vì gcc / clang không bao giờ sử dụng các vị trí args làm không gian đầu, AFAIK.
Peter Cordes

Ngoài ra, nói chung, không an toàn khi gọi printftừ _start(ví dụ trong nhị phân tĩnh), vì vậy đó là một đối số tốt để viết mainthay vì a _start. Câu trả lời này giải thích các cách khác nhau để liên kết libc từ các nhị phân tĩnh hoặc động. (Trong nhị phân động của Linux, trình liên kết động sẽ chạy các hàm khởi tạo của glibc, do đó bạn có thể sử dụng printftừ _startđiểm vào, nhưng đó không phải là trường hợp trên cygwin IIRC.)
Peter Cordes

1

ASM có khả năng khởi động, 660 byte

[bits 16]
mov ax,07C0h
mov ds,ax 
mov ah,0
mov al,03h 
int 10h
mov si,code
call p 
jmp $
p:mov ah,0Eh
r:lodsb
cmp al,0
je d
cmp bx,0x42
jne s
c:int 10h
jmp r
s: cmp al,94 
je re
cmp al,63
je q
jmp c
q:mov al,34
jmp c
re:push si
mov bx,0x42
mov si,code
call p 
mov bx,0
pop si
jmp p 
d:ret
code:db "[bits 16]\mov ax,07C0h\mov ds,ax\mov ah,0\mov al,03h\int 10h\mov si,code\call p\jmp $\p:mov ah,0Eh\r:lodsb\cmp al,0\je d\cmp bx,0x42\jne s\c:int 10h\jmp r\s:cmp al,94\je re\cmp al,63\je q\jmp c\q:mov al,34\jmp c\re:push si\mov bx,0x42\mov si,code\call p\mov bx,0\pop si\jmp p\\d:ret\\code:db ?^?\times 510-($-$$) db 0\dw 0xAA55"
times 510-($-$$) db 0
dw 0xAA55

Ban đầu bởi jdiez17 , chơi golf của bạn thực sự.


0

x86-64, Hệ thống V AMD64 ABI, GASM: 432

.att_syntax noprefix
.globl main
main:
pushq rbp
movq rsp, rbp
mov $.Cs, rdi
mov $0xa, rsi
mov $0x22, edx
mov $.Cs, ecx
mov $0x22, r8d
mov $0xa, r9d
xor eax, eax
call printf
xor eax, eax
leave
ret
.Cs: .string ".att_syntax noprefix
.globl main
main:
pushq rbp
movq rsp, rbp
mov $.Cs, rdi
mov $0xa, rsi
mov $0x22, edx
mov $.Cs, ecx
mov $0x22, r8d
mov $0xa, r9d
xor eax, eax
call printf
xor eax, eax
leave
ret%c.Cs: .string %c%s%c%c"

1
Bạn không cần một khoảng trắng sau dấu phẩy giữa các toán hạng. Và bạn hoàn toàn không cần xor eax,eaxnếu bạn không quan tâm đến trạng thái thoát khỏi chương trình của mình. Nó vẫn tự in, ngay cả khi nó thoát với trạng thái khác không. Bạn cũng có thể sử dụng pushthay vì pushq. Trên thực tế, tại sao bạn thậm chí làm một khung stack? Thả push rbp/ mov rsp, rbpleave. Bạn cũng có thể sử dụng tên nhãn ngắn hơn. .Cslà 3 ký tự khi 1 sẽ ổn.
Peter Cordes

Sau đó, .att_syntax noprefixcó lẽ không trả tiền cho chính nó nữa. .intel_syntax noprefixcũng sẽ cho phép bạn bỏ sáu $tiền tố đó. nhưng có lẽ vẫn không đáng (Bạn có thể sử dụng lea ecx,.Csthay vì cú pháp intel mov ecx,offset .Cs)
Peter Cordes

0

TAL

push puts
push \100
push {push puts
push \100
push {@}
dup
strmap
invokeStk 2}
dup
strmap
invokeStk 2

Để thực hiện nó, gọi ::tcl::unsuppoted::assemblevới mã là đối số.
Chỉ Tcl 8.6.


3
Bạn nên bao gồm số byte.
MD XF

0

TASx 80x86, 561 byte

MODEL TINY
.CODE
.STARTUP
DB 177
DB 076
DB 186
DB 044
DB 001
DB 172
DB 180
DB 036
DB 179
DB 004
DB 191
DB 080
DB 001
DB 079
DB 136
DB 037
DB 212
DB 010
DB 004
DB 048
DB 134
DB 196
DB 075
DB 117
DB 244
DB 180
DB 009
DB 205
DB 033
DB 178
DB 071
DB 226
DB 228
DB 178
DB 038
DB 205
DB 033
DB 195
DB 013
DB 010
DB 069
DB 078
DB 068
DB 036
DB 077
DB 079
DB 068
DB 069
DB 076
DB 032
DB 084
DB 073
DB 078
DB 089
DB 013
DB 010
DB 046
DB 067
DB 079
DB 068
DB 069
DB 013
DB 010
DB 046
DB 083
DB 084
DB 065
DB 082
DB 084
DB 085
DB 080
DB 013
DB 010
DB 068
DB 066
DB 032
END
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.