当我使用 gcd 在线调试时,出现如下所示的未声明变量编译错误
/usr/bin/ld: /tmp/ccQ5mbJk.o: in function \`assemble':
main.c:(.text+0x2ed): undefined reference to \`parseInstruction'
/usr/bin/ld: main.c:(.text+0x316): undefined reference to \`getRegisterNumber'
/usr/bin/ld: main.c:(.text+0x338): undefined reference to \`getRegisterNumber'
/usr/bin/ld: main.c:(.text+0x364): undefined reference to \`getRegisterNumber'
/usr/bin/ld: main.c:(.text+0x463): undefined reference to \`parseDirective'
我需要帮助或建议修复下面的主要部分和空白部分。之前的所有功能都在我的源文件中定义
int main(int argc, char** argv) {
// Checking command line arguments
if (argc < 2) {
printf("Usage: %s <test.asm> <test.out>\n", argv[0]);
return -1;
}
// Initializing memory
int text_segment[MAX_SIZE];
int data_segment[MAX_SIZE];
memset(text_segment, 0, MAX_SIZE);
memset(data_segment, 0, MAX_SIZE);
// Writing to output file
FILE* fp = fopen(argv[2], "w");
fwrite(text_segment, 1, MAX_SIZE, fp);
fwrite(data_segment, 1, MAX_SIZE, fp);
fclose(fp);
return 0;
}
// Assembling the input file
void assemble(char* filename, int* text_segment, int* data_segment) {
int line_number = 0;
int text_offset = 0;
int data_offset = 0;
char line[256];
FILE* fp = fopen(filename, "r");
while (fgets(line, 256, fp)) {
// Handling blank lines
if (strcmp(line, "\n") == 0) {
continue;
}
// Parsing line
char* label = NULL;
char* instruction = NULL;
char* directive = NULL;
char* operands = NULL;
label = strtok(line, ":");
instruction = strtok(NULL, " \n\t");
directive = strtok(NULL, " \n\t");
operands = strtok(NULL, "\n\t");
// Handling instructions
if (instruction) {
// Parsing instruction
int opcode = 0;
int funct = 0;
int rs = 0;
int rt = 0;
int rd = 0;
int imm = 0;
int add = 0;
if (parseInstruction(instruction, &opcode, &funct)) {
rs = getRegisterNumber(strtok(operands, ","));
rt = getRegisterNumber(strtok(NULL, ","));
if (opcode == 0) {
rd = getRegisterNumber(strtok(NULL, ","));
} else {
imm = atoi(strtok(NULL, ","));
}
// Generating machine code
int machine_code = 0;
machine_code |= (opcode << 26);
machine_code |= (rs << 21);
machine_code |= (rt << 16);
machine_code |= (rd << 11);
machine_code |= (imm << 0);
machine_code |= (add << 0);
machine_code |= (funct << 0);
// Writing machine code to text segment
text_segment[text_offset] = machine_code;
text_offset += 1;
}
// Handling directives
if (directive) {
// Parsing directive
int type = 0;
int size = 0;
if (parseDirective(directive, &type, &size)) {
char* token = strtok(operands, ",");
while (token) {
int value = 0;
sscanf(token, "%d", &value);
// Handling .dbyte
if (type == 2) {
data_segment;
// Writing value to data segments
data_segment[data_offset] = value;
data_offset += 1;
}
// Handling .integer
if (type == 3) {
// Writing value to data segment
data_segment[data_offset] = value;
data_offset += 1;
}
token = strtok(NULL, ",");
}
}
}
}
fclose(fp);
}
// Getting MIPS instruction
Instruction* getInstruction(char* instruction) {
int i = 0;
while (instructions[i].name) {
if (strcmp(instructions[i].name, instruction) == 0) {
return &instructions[i];
}
i++;
}
return NULL;
}
// Getting MIPS directive
Directive* getDirective(char* directive) {
int i = 0;
while (directives[i].name) {
if (strcmp(directives[i].name, directive)) {
return &directives[i];
}
i++;
}
return NULL;
}
// Getting register number
int getRegisterNumber(char* regis) {
int reg = 0;
sscanf(regis, "$%d", ®);
return reg;
}
// Parsing instruction
int parseInstruction(char* instruction, int* opcode, int* funct) {
for (int i = 0; instructions[i].name; i++) {
if (strcmp(instruction, instructions[i].name) == 0) {
*opcode = instructions[i].opcode;
*funct = instructions[i].funct;
return 1;
}
}
return 0;
}
// Parsing directive
int parseDirective(char* directive, int* type, int* size) {
Directive* dir = getDirective(directive);
if (dir) {
*type = dir->n;
*size = dir->size;
return 1;
} else {
return 0;
}
}
}
以最高评论为序...
请注意,您的代码(已发布)将无法编译,因为您在
中缺少结束符}
。这可能会导致您的一些问题。此外,您在定义之前调用assemble
。我会使用前向函数声明或重新排序函数。 – 克雷格·埃斯蒂parseInstruction
我将如何宣布?我在这个项目上花费了无数时间—— 安德鲁·谢尔布
还有 assemble } 支架一直在底部,除非我贴错了,或者它不应该在那里?我写了整个汇编来包括它后面的所有东西—— 安德鲁·谢尔布
是的,你有正确数量的
但最后的}
在错误的位置,所以编译器认为你有词法“嵌套”函数(标准 C 中不存在)。 – 克雷格·埃斯蒂}
好吧,我已经重构了代码,所以它可以干净地编译。它仍然有一个关于设置
label
但不使用它的警告。
我不得不综合你的一些missing
struct
定义让它干净地编译。
但是,这解决了您关于缺失功能的原始问题。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// synthesized missing definitions ...
#if 1
#define MAX_SIZE 1024
typedef struct {
char *name;
int n;
int size;
} Directive;
Directive directives[1000];
typedef struct {
char *name;
int opcode;
int funct;
} Instruction;
Instruction instructions[1000];
#endif
// forward function declarations
#if 1
void assemble(char *filename, int *text_segment, int *data_segment);
Instruction *getInstruction(char *instruction);
Directive *getDirective(char *directive);
int getRegisterNumber(char *regis);
int parseInstruction(char *instruction, int *opcode, int *funct);
int parseDirective(char *directive, int *type, int *size);
#endif
int
main(int argc, char **argv)
{
// Checking command line arguments
if (argc < 2) {
printf("Usage: %s <test.asm> <test.out>\n", argv[0]);
return -1;
}
// Initializing memory
int text_segment[MAX_SIZE];
int data_segment[MAX_SIZE];
// NOTE/BUG: compiler warns about third arg being too small
#if 0
memset(text_segment, 0, MAX_SIZE);
memset(data_segment, 0, MAX_SIZE);
#else
memset(text_segment, 0, sizeof(text_segment));
memset(data_segment, 0, sizeof(data_segment));
#endif
// Writing to output file
FILE *fp = fopen(argv[2], "w");
fwrite(text_segment, 1, MAX_SIZE, fp);
fwrite(data_segment, 1, MAX_SIZE, fp);
fclose(fp);
return 0;
}
// Assembling the input file
void
assemble(char *filename, int *text_segment, int *data_segment)
{
// NOTE/BUG: line_number not used
#if 0
int line_number = 0;
#endif
int text_offset = 0;
int data_offset = 0;
char line[256];
FILE *fp = fopen(filename, "r");
while (fgets(line, 256, fp)) {
// Handling blank lines
if (strcmp(line, "\n") == 0) {
continue;
}
// Parsing line
// NOTE/BUG: compiler warning: label set but not used
char *label = NULL;
char *instruction = NULL;
char *directive = NULL;
char *operands = NULL;
label = strtok(line, ":");
instruction = strtok(NULL, " \n\t");
directive = strtok(NULL, " \n\t");
operands = strtok(NULL, "\n\t");
// Handling instructions
if (instruction) {
// Parsing instruction
int opcode = 0;
int funct = 0;
int rs = 0;
int rt = 0;
int rd = 0;
int imm = 0;
int add = 0;
if (parseInstruction(instruction, &opcode, &funct)) {
rs = getRegisterNumber(strtok(operands, ","));
rt = getRegisterNumber(strtok(NULL, ","));
if (opcode == 0) {
rd = getRegisterNumber(strtok(NULL, ","));
}
else {
imm = atoi(strtok(NULL, ","));
}
// Generating machine code
int machine_code = 0;
machine_code |= (opcode << 26);
machine_code |= (rs << 21);
machine_code |= (rt << 16);
machine_code |= (rd << 11);
machine_code |= (imm << 0);
machine_code |= (add << 0);
machine_code |= (funct << 0);
// Writing machine code to text segment
text_segment[text_offset] = machine_code;
text_offset += 1;
}
// Handling directives
if (directive) {
// Parsing directive
int type = 0;
int size = 0;
if (parseDirective(directive, &type, &size)) {
char *token = strtok(operands, ",");
while (token) {
int value = 0;
sscanf(token, "%d", &value);
// Handling .dbyte
if (type == 2) {
// NOTE/BUG: statement with no effect
#if 0
data_segment;
#endif
// Writing value to data segments
data_segment[data_offset] = value;
data_offset += 1;
}
// Handling .integer
if (type == 3) {
// Writing value to data segment
data_segment[data_offset] = value;
data_offset += 1;
}
token = strtok(NULL, ",");
}
}
}
}
fclose(fp);
}
}
// Getting MIPS instruction
Instruction *
getInstruction(char *instruction)
{
int i = 0;
while (instructions[i].name) {
if (strcmp(instructions[i].name, instruction) == 0) {
return &instructions[i];
}
i++;
}
return NULL;
}
// Getting MIPS directive
Directive *
getDirective(char *directive)
{
int i = 0;
while (directives[i].name) {
if (strcmp(directives[i].name, directive)) {
return &directives[i];
}
i++;
}
return NULL;
}
// Getting register number
int
getRegisterNumber(char *regis)
{
int reg = 0;
sscanf(regis, "$%d", ®);
return reg;
}
// Parsing instruction
int
parseInstruction(char *instruction, int *opcode, int *funct)
{
for (int i = 0; instructions[i].name; i++) {
if (strcmp(instruction, instructions[i].name) == 0) {
*opcode = instructions[i].opcode;
*funct = instructions[i].funct;
return 1;
}
}
return 0;
}
// Parsing directive
int
parseDirective(char *directive, int *type, int *size)
{
Directive *dir = getDirective(directive);
if (dir) {
*type = dir->n;
*size = dir->size;
return 1;
}
else {
return 0;
}
}
在上面的代码中,我使用了
cpp
条件来表示旧代码与新代码:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
注意:这可以通过运行文件来清理
unifdef -k