MGTPC/MGTPC.py
2025-07-15 18:33:31 +08:00

300 lines
10 KiB
Python

import tkinter as tk
from tkinter import scrolledtext, messagebox
class AsmToCConverter:
def __init__(self, root):
self.root = root
self.root.title("汇编转C/C++转换器")
self.setup_ui()
# 汇编到C的指令映射
self.asm_to_c = {
'mov': '=', # 赋值
'add': '+', # 加法
'sub': '-', # 减法
'mul': '*', # 乘法
'div': '/', # 除法
'and': '&', # 按位与
'or': '|', # 按位或
'xor': '^', # 按位异或
'shl': '<<', # 左移
'shr': '>>', # 右移
'cmp': '==', # 比较
'jmp': 'goto', # 跳转
'call': '', # 函数调用
'ret': 'return', # 返回
'push': '', # 压栈
'pop': '', # 弹栈
'inc': '++', # 自增
'dec': '--', # 自减
'je': 'if (==)', # 等于跳转
'jne': 'if (!=)',# 不等于跳转
'jg': 'if (>)', # 大于跳转
'jge': 'if (>=)',# 大于等于跳转
'jl': 'if (<)', # 小于跳转
'jle': 'if (<=)' # 小于等于跳转
}
# 寄存器到变量的映射
self.reg_to_var = {
'eax': 'var1',
'ebx': 'var2',
'ecx': 'var3',
'edx': 'var4',
'esi': 'var5',
'edi': 'var6',
'esp': 'stack_pointer',
'ebp': 'base_pointer'
}
def setup_ui(self):
# 主框架
main_frame = tk.Frame(self.root, padx=10, pady=10)
main_frame.pack(fill=tk.BOTH, expand=True)
# 汇编代码输入
tk.Label(main_frame, text="汇编代码:").grid(row=0, column=0, sticky="w")
self.asm_input = scrolledtext.ScrolledText(
main_frame,
width=60,
height=15,
wrap=tk.WORD
)
self.asm_input.grid(row=1, column=0, padx=5, pady=5)
# C代码输出
tk.Label(main_frame, text="C/C++代码:").grid(row=0, column=1, sticky="w")
self.c_output = scrolledtext.ScrolledText(
main_frame,
width=60,
height=15,
wrap=tk.WORD,
state='disabled'
)
self.c_output.grid(row=1, column=1, padx=5, pady=5)
# 按钮框架
btn_frame = tk.Frame(main_frame)
btn_frame.grid(row=2, columnspan=2, pady=10)
# 转换按钮
convert_btn = tk.Button(
btn_frame,
text="转换为C/C++",
command=self.convert_asm_to_c
)
convert_btn.pack(side=tk.LEFT, padx=5)
# 清空按钮
clear_btn = tk.Button(
btn_frame,
text="清空",
command=self.clear_text
)
clear_btn.pack(side=tk.LEFT, padx=5)
# 复制按钮
copy_btn = tk.Button(
btn_frame,
text="复制结果",
command=self.copy_result
)
copy_btn.pack(side=tk.LEFT, padx=5)
# 选项框架
option_frame = tk.Frame(main_frame)
option_frame.grid(row=3, columnspan=2, pady=5)
# 语言选择
self.lang_var = tk.StringVar(value="C")
tk.Label(option_frame, text="输出语言:").pack(side=tk.LEFT)
tk.Radiobutton(
option_frame,
text="C",
variable=self.lang_var,
value="C"
).pack(side=tk.LEFT)
tk.Radiobutton(
option_frame,
text="C++",
variable=self.lang_var,
value="C++"
).pack(side=tk.LEFT)
# 是否添加注释
self.comment_var = tk.BooleanVar(value=True)
tk.Checkbutton(
option_frame,
text="添加注释",
variable=self.comment_var
).pack(side=tk.LEFT, padx=10)
def convert_asm_to_c(self):
"""将汇编代码转换为C/C++代码"""
asm_code = self.asm_input.get("1.0", tk.END).strip()
if not asm_code:
messagebox.showwarning("警告", "请输入汇编代码!")
return
try:
# 清空输出区域
self.c_output.config(state='normal')
self.c_output.delete("1.0", tk.END)
# 添加文件头注释
lang = self.lang_var.get()
if self.comment_var.get():
self.c_output.insert(tk.END, f"/* 由汇编转换而来的{lang}代码 */\n\n")
# 添加基本包含和主函数框架
if lang == "C++":
self.c_output.insert(tk.END, "#include <iostream>\n")
self.c_output.insert(tk.END, "using namespace std;\n\n")
self.c_output.insert(tk.END, "int main() {\n")
# 初始化变量
for reg, var in self.reg_to_var.items():
if var != 'stack_pointer' and var != 'base_pointer':
self.c_output.insert(tk.END, f" int {var} = 0;\n")
if self.comment_var.get():
self.c_output.insert(tk.END, "\n /* 转换后的代码 */\n")
# 处理每一行汇编代码
for line in asm_code.split('\n'):
line = line.strip()
if not line or line.startswith(';'):
continue # 跳过空行和注释
# 移除行尾注释
if ';' in line:
line = line.split(';')[0].strip()
# 转换指令
c_line = self.convert_asm_line(line)
if c_line:
self.c_output.insert(tk.END, f" {c_line}\n")
# 添加主函数结尾
self.c_output.insert(tk.END, " return 0;\n")
self.c_output.insert(tk.END, "}\n")
# 禁用编辑
self.c_output.config(state='disabled')
except Exception as e:
messagebox.showerror("错误", f"转换过程中发生错误:\n{str(e)}")
def convert_asm_line(self, line):
"""转换单行汇编指令为C代码"""
parts = [p.strip() for p in line.split() if p.strip()]
if not parts:
return ""
op = parts[0].lower()
operands = [p.strip(',') for p in parts[1:]]
# 处理标签
if op.endswith(':'):
return f"// 标签: {op[:-1]}"
# 处理常见指令
if op in self.asm_to_c:
c_op = self.asm_to_c[op]
# 处理mov指令
if op == 'mov':
if len(operands) == 2:
dest = self.map_operand(operands[0])
src = self.map_operand(operands[1])
return f"{dest} = {src};"
# 处理算术运算
elif op in ['add', 'sub', 'mul', 'div', 'and', 'or', 'xor', 'shl', 'shr']:
if len(operands) == 2:
dest = self.map_operand(operands[0])
src = self.map_operand(operands[1])
return f"{dest} {c_op}= {src};"
# 处理比较指令
elif op == 'cmp':
if len(operands) == 2:
left = self.map_operand(operands[0])
right = self.map_operand(operands[1])
return f"// 比较: {left} {c_op} {right}"
# 处理跳转指令
elif op.startswith('j'):
if operands:
label = operands[0]
if op == 'jmp':
return f"goto {label};"
else:
return f"if (...) goto {label}; // {op}指令"
# 处理函数调用
elif op == 'call':
if operands:
func = operands[0]
return f"{func}(); // 函数调用"
# 处理返回指令
elif op == 'ret':
return "return;"
# 处理自增自减
elif op in ['inc', 'dec']:
if operands:
var = self.map_operand(operands[0])
return f"{var}{c_op};"
# 处理push/pop
elif op in ['push', 'pop']:
if operands:
var = self.map_operand(operands[0])
return f"// {op} {var}"
# 未知指令
return f"// 未知指令: {line}"
def map_operand(self, operand):
"""映射操作数到C变量或常量"""
# 检查是否是寄存器
if operand.lower() in self.reg_to_var:
return self.reg_to_var[operand.lower()]
# 检查是否是内存引用
if '[' in operand and ']' in operand:
return f"/* 内存引用: {operand} */"
# 检查是否是立即数
if operand.startswith('0x'):
return str(int(operand[2:], 16))
if operand.isdigit() or (operand.startswith('-') and operand[1:].isdigit()):
return operand
# 其他情况(可能是标签或变量)
return operand
def clear_text(self):
"""清空输入和输出"""
self.asm_input.delete("1.0", tk.END)
self.c_output.config(state='normal')
self.c_output.delete("1.0", tk.END)
self.c_output.config(state='disabled')
def copy_result(self):
"""复制结果到剪贴板"""
result = self.c_output.get("1.0", tk.END)
if result.strip():
self.root.clipboard_clear()
self.root.clipboard_append(result)
messagebox.showinfo("成功", "结果已复制到剪贴板!")
else:
messagebox.showwarning("警告", "没有可复制的内容!")
if __name__ == "__main__":
root = tk.Tk()
app = AsmToCConverter(root)
root.mainloop()