0

我试图在c中创建一个汇编器,在其中我从包含命令的文件中获取输入,在这种情况下,branchifequal我然后获取它的操作码,10然后byte[0] = 0xA0我获取下一个4位的寄存器,然后注册下一个 4 但是我如何处理偏移量?假设命令是branchifequal r1 r2 8那么手工组装应该是A1 20 00 08。我知道这是通过检查地址偏移量的前 4 位(即 0)和0000 0000 0000 1000我认为的后 16 位来完成的。应该转换为00 08十六进制。在检查第二个字节中的最后 4 位和第 3 个字节中的 2 位以及第 4 字节中的最后 2 位时,我怎样才能得到这个只是简单的十六进制值本身,这在我的代码中完成。我有同样的问题jump命令也一样。

PR1.C

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    char *ltrim(char *s) {
        while (*s == ' ' || *s == '\t') s++;
        return s;
    }

    char getRegister(char *text) {
        if (*text == 'r' || *text=='R') text++;
        return atoi(text);
    }

    char getHex(char *text){
        int number = (int)strtol(text, NULL, 16);
        char reservednum[5];
        if(number <= 0xFFFF){
            sprintf(&reservednum[0], "%04x", number);
        }
        return atoi(reservednum);
    }

    int assembleLine(char *text, unsigned char* bytes) {
        text = ltrim(text);
        char *keyWord = strtok(text," ");
        if (strcmp("add",keyWord) == 0) {
            bytes[0] = 0x10;
            bytes[0] |= getRegister(strtok(NULL," "));
            bytes[1] = getRegister(strtok(NULL," ")) << 4 | getRegister(strtok(NULL," "));
            return 2;
        }
        else if(strcmp("subtract", keyWord) == 0){
            bytes[0] = 0x50;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
            return 2;
        }
        else if(strcmp("and", keyWord) == 0){
            bytes[0] = 0x20;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
            return 2;
        }
        else if(strcmp("divide", keyWord) == 0){
            bytes[0] = 0x30;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
            return 2;
        }
        else if(strcmp("multiply", keyWord) == 0){
            bytes[0] = 0x40;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
            return 2;
        }
        else if(strcmp("or", keyWord) == 0){
            bytes[0] = 0x60;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getRegister(strtok(NULL, " ")) << 4 | getRegister(strtok(NULL, " "));
            return 2;
        }
        else if(strcmp("halt", keyWord) == 0){
            bytes[0] = 0x00;
            bytes[1] = 0x00;
            return 2;
        }
        else if(strcmp("return", keyWord) == 0){
            bytes[0] = 0x70;
            bytes[1] = 0x00;
            return 2;
        }
        else if(strcmp("addimmediate", keyWord) == 0){
            bytes[0] = 0x90;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getHex(strtok(NULL, " "));
            return 2;
        }
        else if(strcmp("interrupt", keyWord) == 0){
            bytes[0] = 0x80;
            bytes[0] |= getHex(strtok(NULL, " "));
            bytes[1] = 0x00;
            return 2;
        }
        else if(strcmp("push", keyWord) == 0){
            bytes[0] = 0x70;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = 0x40;
            return 2;
        }
        else if(strcmp("pop", keyWord) == 0){
            bytes[0] = 0x70;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = 0x80;
            return 2;
        }
        else if(strcmp("jump", keyWord) == 0){
            bytes[0] = 0xC0;
            bytes[1] = 0x00;
            bytes[2] = 0x00;
            bytes[3] = getHex(strtok(NULL, " "));
            return 4;
        }
        else if(strcmp("branchifequal", keyWord) == 0){
            bytes[0] = 0xA0;
            bytes[0] |= getRegister(strtok(NULL, " "));
            bytes[1] = getRegister(strtok(NULL, " ")) << 4;
            bytes[2] = 0x00;
            bytes[3] = getHex(strtok(NULL, " "));
            return 4;
        }
    }

    int main(int argc, char **argv) {
        FILE *src = fopen(argv[1],"r");
        FILE *dst = fopen(argv[2],"w");
        while (!feof(src)) {
            unsigned char bytes[4];
            char line[1000];
            if (NULL != fgets(line, 1000, src)) {
                printf ("read: %s\n",line);
                int byteCount = assembleLine(line,bytes);
                fwrite(bytes,byteCount,1,dst);
            }
        }
        fclose(src);
        fclose(dst);
        return 0;
    }
4

0 回答 0