问题描述
我有一个可执行文件,它接收一个文件作为参数,它厌倦了解析并将其转换为 ASM x86 (FLEX + YACC)。
问题是我正在尝试制作一个脚本来解析一堆文件并创建 ASM 输出文件,显然文件重定向不起作用,但将输出写入屏幕上。
使用 cmd:
.\mmlp.exe .\in\2.ps1
标准输出的结果:
bits 32
global start
; Needed procedures
extern exit,scanf,printf
; Imports
import exit msvcrt.dll
import scanf msvcrt.dll
import printf msvcrt.dll
; Data segment
segment data use32 class=data
; Format used by scanf & printf
format_d db "%d",0
; Program's variables
x dd 0
; Code segment
segment code use32 class = code
start:
; WRITE TO STDOUT
push dword x
push dword format_d
call [printf]
add esp,4 * 2
; exit(0)
push dword 0
call [exit]
但是如果我试试这个:
.\mmlp.exe .\in\2.ps1 > some-file.asm
文件将为空。
PowerShell 也是一样,尝试了不同的方法,都没有效果
& $exePath @($inFile) | Out-File some-file.asm
or
$result = & $exePath @($inFile)
or
& "cmd.exe" @("/c",$exeFile,$inFile,">","some-file.asm")
没有任何效果,文件仍然是空的。 我什至尝试捕获所有输出流,但结果相同。
int main(int argc,char **argv) {
if (argc == 2) {
yyin = fopen(argv[1],"r");
}
else {
yyin = stdin;
}
asm_segment_data = malloc_list();
asm_segment_code = malloc_list();
int yyparse_result = yyparse();
reverse_list(asm_segment_data);
reverse_list(asm_segment_code);
struct list_node *current;
printf("%s%s",ASM_FILE_HEADER,ASM_SEGMENT_DATA);
for(current = asm_segment_data->root; current != NULL; current = current->next) {
printf("%s",current->value);
}
printf("%s",ASM_SEGMENT_CODE);
for(current = asm_segment_code->root; current != NULL; current = current->next) {
printf("%s",current->value);
}
printf("%s",ASM_EXIT);
free_list(asm_segment_data);
free_list(asm_segment_code);
return yyparse_result;
}
基本上,我有一堆 printf 的。
我正在考虑提供第二个参数并写入该文件,但在某种程度上我更喜欢这种方法,因为它给了我更大的灵活性。 很明显,我做错了什么,但我看不出是什么。
更新:这是我编译可执行文件的方式(PowerShell):
$yaccFileNameFullPath = Join-Path -Path $WorkingDir -Childpath $YaccFileName
& "bison" @("-y","-d",$yaccFileNameFullPath)
$flexFileNameFullPath = Join-Path -Path $WorkingDir -Childpath $FlexFileName
& "flex" @($flexFileNameFullPath)
& "gcc" @("lex.yy.c","y.tab.c","-o",$exeFullPath)
更新 2:
我尝试了评论中推荐的所有内容,使用 fprintf(stdout...) 而不是 printf,但这没有用。文件的扩展名无关紧要,尝试了一堆。名称基本上只是一个单词和一个数字 [example1.extension]。
我最后只添加了另一个参数,它代表输出文件的路径。打开那个文件,用fprintf写入,还是什么都没有。
不知何故,我最终注释掉了这些行,这反过来又成功地完成了写入文件的操作。
// free_list(asm_segment_data);
// free_list(asm_segment_code);
free_list 函数:
void free_list(struct list *list)
{
struct list_node *current;
for (current = list->root; current != NULL; current = current->next)
{
free(current);
}
free(list);
}
为什么最终会有内存泄漏?我知道我正在释放分配的字符数组,但是 printf/fprintf 不应该写一个副本吗?这段记忆是否有某种联系?刷新/关闭文件后我应该释放吗?
这就是我为 list_node 值分配内存的方式
#define ASM_FORMAT_ASSIGNMENT "\
; ASSIGNMENT\n\
mov AX,[%s]\n\
mov [%s],AX\n\n\
"
char *asm_assignment(char *from,char *to)
{
char *buffer = (char *)malloc((strlen(ASM_FORMAT_ASSIGNMENT) +
strlen(from) +
strlen(to) + 1) *
sizeof(char));
sprintf(buffer,ASM_FORMAT_ASSIGNMENT,from,to);
return buffer;
}
然后我在 YACC 文件中以匹配模式使用它,如下所示:
assignment : ID ASSIGNMENT_OPERATOR operation {
memmove($1,$1 + 1,strlen($1)); // Remove '$' from variable name.
char *buffer = asm_assignment($3,$1);
printf("[mmlp.y] NEW ASM_ASSIGNMENT %s\n",buffer);
add_list(asm_segment_code,buffer);
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)