씨, 924 838 825 696 646 623
나는 b
명령어에 지정된 레지스터에 "포인터"(바이트 오프셋)를 저장하고, 나중에 레지스터에 액세스 할 때와 동일한 방식으로 (또는 포인터를 재구성하기 위해 반대로) 의사 코드에서 배열을 지정하는 레지스터를 사용합니다. 여전히 테스트 프로그램을 시도해야합니다 ...
편집 : 의견을 추가했습니다.
편집 : 고정 명령 12. 메모리의 명령이 아닌 포인터를 변경하십시오. 개수는 모든 주석, 들여 쓰기 및 줄 바꿈이 제거 된 상태입니다.
편집 : 결과를 올바르게 해석한다고 가정하면 현재 실행중인 것으로 보입니다. :) 최종 구현은 0 배열 이 실제로 핸들 0에 의해 참조되고 초기화되지 않은 레지스터에서 발견 될 수 있다는 것입니다. 꼬인 작은 기계! :)
편집 : ... write
대신 사용할 디버깅 장치를 다시 작성했습니다 printf
. 여기서 아이디어는 버그 를 제거하는 것 입니다. :) 편집 : putchar()
와 getchar()
도 아무-번호 없습니다 sbrk
. 이제 작동하고 매우 빠르게 나타납니다.
#define O(_)*a=*b _*c;B
#define B break;case
#define U unsigned
U*m,r[8],*p,*z,f,x,*a,*b,*c;main(int n,char**v){U char
u[4];z=m=p=sbrk(4);f=n>1?open(v[1],0):0;\
while(read(f,u,4)){*m++=(((((*u<<8)|u[1])<<8)|u[2])<<8)|u[3];sbrk(4);}sbrk(4);\
for(;x=*p++,1;){c=r+(x&7);b=r+((x>>3)&7);a=r+((x>>6)&7);switch(x>>28){case
0:*c?*a=*b:0;B
1:*a=(*b?m+*b:z)[*c];B
2:(*a?m+*a:z)[*b]=*c;B
3:O(+)4:O(*)5:O(/)6:*a=~(*b&*c);B
7:return 0;case
8:*b=1+(U*)sbrk(4*(1+*c))-m;(m+*b)[-1]=*c;B
9:B
10:*u=*c;write(1,u,1);B
11:read(0,u,1);*c=*u;B
12:*b?memcpy(z=sbrk(4*(m+*b)[-1]),m+*b,4*(m+*b)[-1]):0;p=&z[*c];B
13:a=r+((x>>25)&7);*a=x&0x1ffffff;}}}
리틀 엔디안 전용의 경우 611 자 버전이 있습니다.
#define O(_)*a=*b _*c;B
#define B break;case
#define U unsigned
U*m,r[8],*p,*z,f,x,*a,*b,*c;main(int n,char**v){U char
u[4];z=m=p=sbrk(4);f=n>1?open(v[1],0):0;while(read(f,u,4)){*m++=(((((*u<<8)|u[1])<<8)|u[2])<<8)|u[3];sbrk(4);}sbrk(4);for(;x=*p++,1;){c=r+(x&7);b=r+((x>>3)&7);a=r+((x>>6)&7);switch(x>>28){case
0:*c?*a=*b:0;B
1:*a=(*b?m+*b:z)[*c];B
2:(*a?m+*a:z)[*b]=*c;B
3:O(+)4:O(*)5:O(/)6:*a=~(*b&*c);B
7:return 0;case
8:*b=1+(U*)sbrk(4*(1+*c))-m;(m+*b)[-1]=*c;B
9:B
//10:*u=*c;write(1,u,1);B //generic
10:write(1,c,1);B //little-endian
//11:read(0,u,1);*c=*u;B //generic
11:read(0,c,1);B //little-endian
12:*b?memcpy(z=sbrk(4*(m+*b)[-1]),m+*b,4*(m+*b)[-1]):0;p=&z[*c];B
13:a=r+((x>>25)&7);*a=x&0x1ffffff;}}}
(확장 된) 주석 처리 된 디버깅 장치로 들여 쓰기 및 주석 처리됨.
//#define DEBUG 1
#include <fcntl.h> // open
#include <signal.h> // signal
#include <stdio.h> // putchar getchar
#include <string.h> // memcpy
#include <sys/types.h> // open
#include <sys/stat.h> // open
#include <unistd.h> // sbrk read
unsigned long r[8],*m,*p,*z,f,x,o,*a,*b,*c; // registers memory pointer zero file working opcode A B C
char alpha[] = "0123456789ABCDEF";
//void S(int x){signal(SIGSEGV,S);sbrk(9);} // autogrow memory while reading program
void writeword(int fd, unsigned long word){
char buf[8];
unsigned long m=0xF0000000;
int off;
for (off = 28; off >= 0; m>>=4, off-=4) {
buf[7-(off/4)]=alpha[(word&m)>>off];
}
write(fd, buf, 8);
write(fd, " ", 1);
}
int main(int n,char**v){
#ifdef DEBUG
int fdlog;
#endif
unsigned char u[4]; // 4-byte buffer for reading big-endian 32bit words portably
int cnt;
#ifdef DEBUG
fdlog = open("sandlog",O_WRONLY|O_CREAT|O_TRUNC, 0777);
#endif
z=m=p=sbrk(4); // initialize memory and pointer
//signal(SIGSEGV,S); // invoke autogrowing memory -- no longer needed
f=n>1?open(v[1],O_RDONLY):0; // open program
while(read(f,u,4)){ // read 4 bytes
*m++=(((((*u<<8)|u[1])<<8)|u[2])<<8)|u[3]; // pack 4 bytes into 32bit unsigned in mem
sbrk(4); // don't snip the end of the program
}
sbrk(4);
for(cnt=0;x=*p++,1;cnt++){ // working = *ptr; ptr+=1
c=r+(x&7); // interpret C register field
b=r+((x>>3)&7); // interpret B register field
a=r+((x>>6)&7); // interpret A register field
#ifdef DEBUG
{int i;write(fdlog,"{",1);for(i=0;i<8;i++)writeword(fdlog, r[i]);
write(fdlog,"} ",2);
}
write(fdlog, alpha+(x), 1);
write(fdlog, alpha+(x>>28), 1);
#endif
switch(o=x>>28){ // interpret opcode
case 0:
#ifdef DEBUG
write(fdlog, "if(rX)rX=rX\n", 12);
#endif
*c?*a=*b:0;
break; // Conditional Move A=B unless C==0
case 1:
#ifdef DEBUG
write(fdlog, "rX=rX[rX]\n", 10);
#endif
*a=(*b?m+*b:z)[*c];
break; // Array Index A=B[C]
case 2:
#ifdef DEBUG
write(fdlog, "rX[rX]=rX\n", 10);
#endif
(*a?m+*a:z)[*b]=*c;
break; // Array Amendment A[B] = C
case 3:
#ifdef DEBUG
write(fdlog, "rX=rX+rX\n", 9);
#endif
*a=*b+*c;
break; // Addition A = B + C
case 4:
#ifdef DEBUG
write(fdlog, "rX=rX*rX\n", 9);
#endif
*a=*b**c;
break; // Multiplication A = B * C
case 5:
#ifdef DEBUG
write(fdlog, "rX=rX/rX\n", 9);
#endif
*a=*b/ *c;
break; // Division A = B / C
case 6:
#ifdef DEBUG
write(fdlog, "rX=~(rX&rX)\n", 12);
#endif
*a=~(*b&*c);
break; // Not-And A = ~(B & C)
case 7:
#ifdef DEBUG
write(fdlog, "halt\n", 5);
#endif
return 0; // Halt
case 8:
#ifdef DEBUG
write(fdlog, "rX=alloc(rX)\n", 13);
#endif
*b=1+(unsigned long*)sbrk(4*(1+*c))-m;
(m+*b)[-1]=*c;
break; // Allocation B = allocate(C)
case 9:
#ifdef DEBUG
write(fdlog, "free(rX)\n", 9);
#endif
break; // Abandonment deallocate(C)
case 10:
#ifdef DEBUG
write(fdlog, "output(rX)\n", 11);
#endif
//putchar(*c);
//*u=u[1]=u[2]=' ';
u[3]=(char)*c;
write(fileno(stdout), u+3, 1);
break; // Output char from C to stdout
case 11:
#ifdef DEBUG
write(fdlog, "rX=input()\n", 11);
#endif
//x=getchar();*c=x;
read(fileno(stdin), u+3, 1);
*c=u[3];
break; // Input char from stdin into C
case 12:
#ifdef DEBUG
write(fdlog, "load(rX)[rX]\n", 13);
#endif
*b?memcpy(z=sbrk(4*(m+*b)[-1]),m+*b,4*(m+*b)[-1]):0;
p=&z[*c];
break; // Load Program copy the array B into the 0 array, Ptr=C
case 13:
#ifdef DEBUG
write(fdlog, "rX=X\n", 5);
#endif
a=r+((x>>25)&7);*a=x&0x1ffffff; // Orthography REG=immediate-25bit
}
}
}