【问题标题】:How Do You Make An Assembler? [closed]你如何做一个汇编程序? [关闭]
【发布时间】:2011-01-29 12:08:52
【问题描述】:

我想做一个简单的 x86 汇编器。我想知道是否有制作自己的汇编程序的教程。或者,如果有一个我可以学习的简单汇编程序。

另外,我想知道在查看和处理程序的二进制/十六进制时使用了哪些工具。

【问题讨论】:

  • 我更喜欢用 C 开发汇编程序。
  • stackoverflow.com/questions/1669/learning-to-write-a-compiler 中列出的一些参考资料可能将此视为编译阶段(有些可能没有)。 [[相关,重复。]]
  • 也看看@《如何写反汇编程序?》 stackoverflow.com/questions/924303/how-to-write-a-disassembler
  • 这是有效的,并且不会太宽泛; OP 只是在寻找有关它的教程或资源。为 Stack Overflow 编写汇编器是否过于宽泛高层家伙..
  • 我正在编写自己的 6502 汇编编译器,我就是这样做的:使用正则表达式字符串来识别助记符(即命令)、任何特殊括号和带有正则表达式回溯的特殊符号(对于不同的寻址模式),以及正则表达式十六进制、二进制和十进制识别。然后设置助记符识别例程来识别每个助记符的变化,并将适当的字节发送到输出文件。您只需要一个助记符列表、它们的寻址模式、语法和操作码。

标签: x86 assembly


【解决方案1】:
【解决方案2】:

只是 Delphi 7 中的一小段代码。

{$APPTYPE CONSOLE}
program assembler;
uses sysutils;
const
s1=#0#77#1#90#59#64#4#80#1#69#3#76#1#1#1#1#14#224#2#15#1#1#1#11#1#1#1#1#1#64#13+
#116#1#16#13#64#3#16#4#2#3#1#8#3#2#10#7#32#4#2#7#3#5#16#4#16#5#1#10#16#13#16#3+
#184#124#184#5#16#3#184#5#2#15#96#3#224#173#52#1#16#3#40#1#16#23#65#1#16#3#80#1+
#16#7#75#1#69#1#82#1#78#1#69#1#76#1#51#1#50#1#46#1#68#1#76#1#76#4#71#1#101#1+
#116#1#83#1#116#1#100#1#72#1#97#1#110#1#100#1#108#1#101#4#87#1#114#1#105#1#116+
#1#101#1#67#1#111#1#110#1#115#1#111#1#108#1#101#1#65#2#72#1#101#1#108#1#108#1+
#111#1#44#1#32#1#87#1#111#1#114#1#108#1#100#1#33#1#13#1#10#5#0;
s3=#1#185#1#7#4#136#1#195#1#128#1#227#1#15#1#193#1#216#1#4#1#128#1#251#1#9+
#1#118#1#3#1#128#1#195#1#39#1#128#1#195#1#48#1#136#1#153#1#96#1#16#1#64#2#73#1+
#125#1#228#1#106#2#104#1#112#1#16#1#64#2#106#1#8#1#104#1#96#1#16#1#64#2#106#1+
#245#1#255#1#21#1#40#1#16#1#64#2#80#1#255#1#21#1#44#1#16#1#64#2#195;
var
  f:file of byte;p,i:integer;o:string;
  t:text;line:string;
procedure w(s: string);
begin
  i:=1;
  while i<length(s) do begin
    inc(p,ord(s[i]));
    setlength(o, p);
    o[p]:=s[i+1];
    inc(i,2);
  end;
end;
procedure al(b: byte);
var
  a: longword;pc: pchar;
begin
  a := strtoint(line); pc:=@a;
  o := o + chr(b) + pc^ + (pc+1)^ + (pc+2)^ + (pc+3)^; inc(p,5); // mov eax, imm32
end;
begin
  assign(f,'out.exe');
  rewrite(f);
  p:=1;
  w(s1);
  assignfile(t, ''); reset(t);
  while not eof(t) do begin
    readln(t, line); line := trim(line);
    if copy(line,1,8) = 'mov eax,' then begin
      system.delete(line,1,8);
      al($b8); // mov eax, imm32
    end
    else if copy(line,1,8) = 'add eax,' then begin
      system.delete(line,1,8);
      al($05); // add eax, imm32
    end
    else if copy(line,1,8) = 'and eax,' then begin
      system.delete(line,1,8);
      al($25); // and eax, imm32
    end
  end;
  closefile(t);
  w(s3);
  blockwrite(f,o[1],p); close(f);
end.

汇编器只能理解三种不同的汇编代码“mov eax,immed32”、“add eax,immed32”、“and eax,immed32”,没有数据也没有标签。它将生成一个很小的 ​​Windows PE 可执行文件,最后以十六进制输出 eax。

注意:在我的情况下,avira 免费防病毒软件不喜欢输出。这是一个误报。我不得不关闭实时保护。如果您不确定这是否是恶意软件,请使用调试器检查结果(不是!)

【讨论】:

  • 为什么是 Delphi 而不是 C 或 C++?我认为不再有使用 Delphi 的软件构建器了。你能把这段代码翻译成 C 或 C++ 吗?
【解决方案3】:

很久以前写过一篇。就像从 Intel 获取 x86 汇编器参考指南一样简单,并将字节写入 .com 文件(对于 Windows)。我希望我能找到我在上面发布的旧论坛帖子。它写在D++。只是表明你可以用任何语言做到这一点。只需标记您的字符串并翻译它。

【讨论】:

  • 你用什么做标题?
  • 老实说,我不记得了,因为它已经快 15 年了,但我认为您不必为 .com 可执行文件。
  • 我刚刚检查过,你是对的,.com 没有标题,只有代码和数据。你是如何执行二进制文件的?你是直接在 Windows 上执行的吗?
  • 如果我没记错的话,我只是在编译后从 DOS 的命令行中调用了 .com。
【解决方案4】:

就示例代码而言...

不过,我不知道任何“简单”的汇编程序。

【讨论】:

    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 2010-10-08
    • 2011-05-24
    • 2021-07-24
    • 2014-12-26
    相关资源
    最近更新 更多