#16 "(}23!@)(" 3//*v\D@;'[af2.qc]'#)"14";n4
#/*` PkPPZ (22)S"[!(>7 7*,;68*,@;'1,@␉␉␉␉ q
#>␉
# >36!@␉
#`<`
#<]+<[.>-]>[
#{
#z}
#
#=x<R+++++[D>+++++++EAL+++<-][pPLEASE,2<-#2DO,2SUB#1<-#52PLEASE,2SUB#2<-#32DOREADOUT,2DOGIVEUPDOiiipsddsdoh]>+.-- -. >][
#x%+>+=+~tt .
#D>xU/-<+++L
#R+.----\).>]|
#[#[(}2}20l0v01k1kx0l0ix0jor0h0h1d111x0eU0bx0b0o1d0b0e0e0@O6O4/0m1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10vx0v0l111111^_) 0046(8+9+9+9+9+=!)
###|
'\';echo 50;exit;';print((eval("1\x2f2")and(9)or(13))-(0and 4)^1<<(65)>>(62))or"'x"or'({({1})({1}[(0)])}{1}\{1})'#}#(prin 45)(bye)|/=1/24=x<$+@+-@@@@=>+<@@@=>+<?#d>+.--./
__DATA__=1#"'x"//
#.\."12"__*'
###;console.log 39
""""#//
=begin //
#sseemeePaeueewuuweeeeeeeeeeCisajjap*///;.int 2298589328,898451655,12,178790,1018168591,84934449,12597/*
#define p sizeof'p'-1?"38":"37"
#include<stdio.h>
main ( )/*/
#
#"`#"\'*/{puts (p);}/*'"`"
/*
<>{#65}//
#}
disp 49#//
#{
1}<>//
$'main'//
#-3o4o#$$$
#<R>"3"O.
=end #//
"""#"#//
#}
#s|o51~nJ;#:p'34'\=#print (17)#>27.say#]#print(47)#]#echo 21
#sss8␛dggi2␛ `|1|6$//''25 16*///89^_^_Z222999"26
␉
리터럴 탭, ␛
리터럴 ESC 문자입니다. 그렇지 않으면 스택 익스체인지가 프로그램을 혼란시킬 것입니다. 작업하려면 아래 TIO 링크의 "입력"상자에서 프로그램을 복사하는 것이 좋습니다.
자세한 내용을 원하십니까? polygot 채팅을 보십시오 !
온라인으로 사용해보십시오!
VIP 점수 ( Versatile Integer Printer ) : .008186 (개선하려면 다음 항목은 1151 바이트를 넘지 않아야 함)
이 프로그램 은 어셈블리 51 , 배쉬 50 , 옥타브 49 , 데드 피쉬 48 , 릴리 47 , 큐빅스 46 , 피코 리스프 45 , 알프 룩 44 , 망상 43 , 악 42 , 뇌 41 , 40 최소한도 2d에서 39 커피 스크립트에서 38 C에서 37 C ++에서 36 미로, 35 INTERCAL에서 34 레일, 33 사건에서, 32 소용돌이에,모듈 식 SNUSP 31 , 공백 30 , 트리거 29 , Brain-Flak 28 , Perl 6 27 , 05AB1E 26 , Pip 25 , Thutu 24 , Hexagony 23 , Underload 22 , Nim 21 , 20 in 서곡, 19 Reng에서 18 카디날에서 17 줄리아에서 16 Pyth에서 15 덤에서 14 Turtlèd에서 13 루비에서 12 분열에서 11 비 펀지-98,10 비 펀지-93에서9 펄 5에서 8 망막, 7 JAPT에서 6 SMBF에서 5 파이썬 2에서 4 에> <> 3 Minkolang에서 2 V / 빔, 그리고 1 파이썬 3인치
확인
대부분의 언어는 위에 표시된 테스트 드라이버로 테스트됩니다.
Reng은 여기서 출력 19로 테스트 할 수 있습니다 .
모듈 형 SNUSP는 여기서 출력 31로 테스트 할 수 있습니다 .
Cubix의 큐브 모양은 볼 여기
사건은 이전 답변에서 설명한대로 토큰의 균형을 유지하여 확인합니다.
Deadfish ~ 들어, 출력 48로 테스트 할 수 있습니다 이와 함께 . Deadfish ~는 표준 입력에 폴리 글롯을 공급하지만 >>
Deadfish ~ 프로그램을 실행하면 피할 수없는 많은 결과를 표준 출력으로 인쇄합니다 .
여기서 출력 51로 어셈블리 테스트 가능
감사와 축하
@ ais523의 50-in-1k 답변이 2 주 전에 떨어졌을 때, 눈물이 뺨을 굴렀습니다. 너무 아름다웠다. 그리고 그것은 Bash에있었습니다. 너무 완벽했습니다.
나는 아내에게 눈물을 흘렸다.
그녀는 나를보고 눈을 돌리고 잠시 멈췄다. 이제 쓰레기를 꺼내십시오.”
그녀의 의미는 그녀와 저의 인터넷 친구들에게 깊은 기쁨을 느꼈다는 것입니다. 모두에게 감사와 축하를 전합니다.
조립 설명
그 후로, 내 마음은 Bash를 게시하기 직전에 폴리 글 로트 채팅에서 @ ais523이 말한 내용으로 되돌아 갔다. 그는 몇 가지 맛의 어셈블리는 #
라인 주석과/*
블록 주석이 . 다음 2 주 동안 천천히 내 마음을 잃을만큼 충분했습니다.
폴리 글 로트에는 합법적 인 언어를 포함시키기위한 암시적인 도전이 있습니다. 나는 여기에 합법적이라는 용어를 매우 느슨하게 사용하고 있지만, 내가 얻는 것을 모두 파악할 수 있다고 생각합니다. Brainf ***를 포함시키는 것은 한 가지 일이지만 Mathlab 또는 R과 같은 것을 포함하는 것은 또 다른 일입니다. Assembly는 확실히 후자 범주에 속하며 내 마음은 그것을 놓을 수 없었습니다. 그러나 나는 의회에 대해 아무것도 몰랐기 때문에 이것은 오르막길이었습니다.
어셈블리와 C / C ++가 공존 할 방법을 찾기 위해 잠시 동안 문제에 대해 머리를 두드리고 나서 이것이 GNU 어셈블러에 대한 문서라는 것을 알았습니다.
과거 어셈블러와 호환되도록 '#'으로 시작하는 행에는 특별한 해석이 있습니다. '#'다음에는 절대 표현식이어야합니다 (식 참조) : 다음 행의 논리 행 번호. 그런 다음 문자열 (문자열 참조)이 허용됩니다. 존재하는 경우 새 논리 파일 이름입니다. 줄의 나머지 부분은 공백이어야합니다.
이것은 폴리 글 로트의 1 행에있는 C / C ++에 대한 사전 프로세서 지시문과 매우 유사한 것으로 나타났습니다. 시행 착오 후에 나는 그것을 발견했다.#1 “bla” 1//*
어셈블리에 대해서만 블록 주석을 입력 .
그래서 폴리 글롯이 만들어졌습니다.
가장 큰 블로킹 문제가 해결되면서 저는이 Hello World 예제를 골프로 시작했습니다.
.intel_syntax noprefix
.section .data
msg: .asciz "51"
.section .text
.global _start
_start:
# write syscall
mov rax, 1
# file descriptor, standard output
mov rdi, 1
# message address
mov rsi, OFFSET FLAT:msg
# length of message
mov rdx, 14
# call write syscall
syscall
#End the Program
mov rax, 60
mov rdi, 0
syscall
기본 저자의 크레딧
사실 나는 1 분 전에 거짓말을했습니다. 제가 사용한 어셈블리 코드의 첫 번째 버전은 어셈블리의 두 가지 구문 중 하나 인 AT & T 구문이었습니다. AT & T 구문의 주요 요소 중 하나는 레지스터 참조가 %
접두사를 사용한다는 것 입니다. 이것이 폴리 글롯에 문제가됩니다. 카디널은 %
포인터 원점으로 사용하기 때문에 우리가 많은 것을 흩 %
뜨리면 두 번째 핵분열 반응과 같습니다.
%
레지스터 접두사로 사용하지 않는 다른 구문 분기를 Intel 구문이라고합니다. 폴리 글롯에서 첫 줄을 넘어 블록 주석을 입력하기 위해 사용하는 익스플로잇은 GNU 어셈블러 (GAS 또는 AS)에 있습니다. AS는 두 가지 구문 분기를 모두 허용하는 행복한 기능을 가지고 있습니다. 어셈블리 코드의 1 행에서 발생하는 Intel 구문을 사용한다고 선언하기 만하면됩니다.
어셈블리는 액세스 속도를 위해 문자 그대로 CPU에 위치한 적은 수의 메모리 위치 인 레지스터를 사용합니다. 이것은 사용이 개발자의 관심사에서 추상화되지 않았다는 것 외에는 어셈블리에 고유하지 않습니다.
다른 목적으로 사용되는 다양한 종류의 레지스터가 있습니다. Wikipedia에서 :
• AX 곱하기 / 나누기, 문자열로드 및 저장
• 문자열 연산 및 시프트에 대한 CX 수
• IN 및 OUT 용 DX 포트 주소
• MOVE 용 BX 인덱스 레지스터
• SP가 스택의 상단을 가리킴
• BP는 스택 프레임의베이스를 가리 킵니다.
• SI는 스트림 작업에서 소스를 가리킴
• DI는 스트림 작업에서 대상을 가리 킵니다.
AX는 여기서 _start 함수 라인에 사용됩니다 mov rax, 1
. r
에서이 rax
메모리는 64 비트임을 나타낸다. 이것을 이것을로 바꾸면 e
32 비트 메모리를 나타내며 64 비트 프로세서와 함께 사용할 수 있습니다. 우리는 사용 가능한 메모리의 상위 절반을 사용하지 않을 것입니다. 16 비트 메모리를 나타내려면을 사용하면 ax
정수를 인쇄하기 때문에 좋습니다. 따라서 모든 레지스터 참조를 16 비트로 변경하여 몇 바이트를 골프화 할 수 있습니다.
좋아, 모든 레지스터 참조가을 삭제할 수있는 것은 아닙니다 r
. mov rsi, OFFSET FLAT:msg
. Assembly에 익숙하지만이 문장에 익숙하지 않은 경우 이는 AS에 반 고유하기 때문입니다. 적어도, 내가 이것 에서 모은 것은 저에게 그 진술을 금으로 내리는 데 도움이되었습니다 lea rsi,m
.
이 후, 나는 경험적으로 나는 노크 수 있다는 것을 발견 _start:
단지 아래로 _p
절단 .global _start
발행 경고 만 전적으로. 둘째, msg:
하나의 문자 변수로 축소되었습니다 p:
. Alphuck의 이익을 위해 추가 된 p
일부 s
어셈블리 를 상쇄 하기 위해 문자열 변수와 시작 기능을 모두 선택했습니다 .
그런 다음 ;
명령을 모두 한 줄에 넣으려면 명령을 구분하십시오. 이것은 주로 #//
Thutu의 이익을 위해 각 줄에 과도한 흔적 을 피하기 위한 것입니다. 또한 어셈블러가 대소 문자를 구분하지 않는 것으로 나타 났으므로 인시던트 불균형을 피하기 위해 다양한 문자를 대문자 또는 소문자로만 표시했습니다.
이 골프는 우리에게
.intel_syntax noprefix;.text;mov ax,1;mov di,1;lea rsi,m;mov dx,2;syscall;mov ax,60;mov di,0;syscall;m:.asciz "51"
이 후, Japt와 Underload는이 답변에서 유일한 문제가 된 어린이였습니다. Japt은 *
1 행에 쇠고기를 추가했지만 puts(p);
C ++ 답변에서 해당 라인 으로 되돌려 고정 된 것으로 보입니다 . 나는 (
이 라인에도을 던지고 Octive 라인에서 닫았습니다. 이것은 Underload가 sefaulting을 중지 할 수 있도록하기위한 것입니다. *
거기 에 추가하기 위해 유사한 처리가 라인 1에서 이루어 졌다.
이것은이 과제의 바이트 요구 사항을 충족시키기에 충분했습니다. 사실 저는 이 버전 의 폴리 글 로트를 만들어서 이것을 확인했습니다 . 그러나 가능하면 VIP 점수를 높이려고 노력했습니다. 그리고 도전 과제의 모든 요구 사항을 충족했기 때문에 코드를 골프화하기 위해 협력하는 것이 좋습니다. 그래서 나는 골프를 치기 위해 폴리 글롯 채팅에 들렀습니다.
우리는 더 깊이 가야한다
@ ais523은이 명령문을 사용하여 명령어를 기계어 코드로 어셈블러에 전달하는 기술을 보여주었습니다.
.text;.long 2298589328,898451655,12,178790,1018168591,84934449,12597
머신 코드는 CPU에서 직접 실행하는 일련의 숫자 명령으로 10 진수, 16 진수 또는 8 진수로 표시 할 수 있습니다. 우리의 목적을 위해 십진수는 가장 짧은 것입니다 (16 진수는 대표 0x
를 나타냅니다). .long
여기에 나오는 내용은 다음에 나오는 일련의 10 진수 기계 코드 명령어임을 선언합니다.
글쎄, 나는 어셈블러가 무엇을 허용하는지 알기 위해이 문장을 찌르고 몇 가지를 변경했다. 첫째, .text;
경고 문제만으로 모두 함께 제거 할 수 있음을 발견했습니다 . 이는 판매량이 많은 바이트 절약이었습니다. 그런 다음 잠시 후 AS 사양 문서 에서이 진술 을 찾았습니다.
.long은 .int와 동일
시원한. 그래서 우리는 빠른 스왑을 위해 스왑을 만들 수 있습니다. 이제 우리의 어셈블리이지만 실제로 기계 코드는 다음과 같이 축소되었습니다.
.int 2298589328,898451655,12,178790,1018168591,84934449,12597
.
이것은 모두 훌륭하지만 기계 코드를 직접 사용하는 것은 매우 어렵고 적어도 모든 번역을 수행하는 방법을 알고 싶었습니다. 따라서 이상적으로 기계 코드를 어셈블리로 분해하고 싶습니다. 가장 쉬운 방법은 @ ais523이이 코드 스 니펫으로 나에게 보여준 객체 덤프를 얻는 것입니다.
다음은 코드 스 니펫입니다.
여기 의회가 있습니다.
nop
mov $0x1,%al
mov %eax,%edi
lea 0xc(%rip),%rsi
mov $0x2,%dx
syscall
mov $0x3c,%al
xor %edi,%edi
syscall
.byte 0x35
xor %eax,(%rax)
이 링크에는 각 어셈블리 라인과 함께 2 자 16 진 숫자도 표시됩니다. 그것들은 십진법에 해당합니다. 당신이 넣어 예를 들어, 2298589328
에 이 진수로 변환 진수, 당신은 얻을 8901B090
다시. 그리고 자세히 살펴보면, 이는 객체 덤프에서 처음 4 개의 16 진 명령입니다 (역순).
내가 알 수 있듯이 4 개의 16 진수 세트는 항상 십진수로 변환하는 데 사용되며 여기서 사용되는 주 바이트 절약 트릭은 4 세트의 마지막 몇 16 진수가 00이되도록 어셈블리를 구조화하는 것입니다. 우리 .int
가 그냥 생략 된 문장에 넣을 때 선행 0으로
이것이 12
성명서 에서 일어나는 일입니다 . 오브젝트 덤프의 16 진 부분에서 이것은입니다 0c 00 00 00
.
이것은 2 주 만에 의회에 대한 나의 이해가 얻은 한입니다. 충돌 코스!
사건
사건은 더 짧은 어셈블리 구현에서 더 어려운 문제였습니다. 사건 보고서는 다음과 같습니다.
!
2 행에서 !
EA
INTERCAL 라인 의 첫 번째 는 자체를 해독합니다.
두 번째 행에서 마지막 행의 마지막 공간은 공간 공간 토큰을 해독합니다.
85
마지막 줄에서
R
에서 #<R>"3"O.
detokenizesR
65
에서 <>{#65 }//
토큰 화65
16
마지막 줄에서 스스로를 해독합니다
89
마지막 줄에 스스로를 토큰 화합니다
추기경
방금 문서화를 잊어 버린 추기경을 변경 한 것을 알았습니다. 나는 바이트를 절약 할 수있는 방법을 찾기 위해 시간을 내며 Cardinal을 배우기로 결정했습니다. 문서와 약간의 시간을 보낸 후에이 줄을 보았습니다.
=
포인터의 활성 값을 비활성 값으로 복사합니다.
이것은 폴리 글롯에서 사용되는 트릭이 아닙니다. 이전 솔루션에는 다음과 같은 지시 사항이 포함되었습니다.`++ ~ * t
++
최대 2 개를 요구합니다.
~
활성 스택을 변경합니다
*
스택을 추가합니다.
나는 ~*
단지 =
명령 으로 달성 할 수 있다는 것을 깨달았 으므로 쓸모없는 스택 스왑을 꺼내고이 작은 바이트 절약을 추가하기 위해 솔루션을 재 작업했습니다.