Assembly 二进制编程资源

Assembly 二进制编程资源,assembly,binary,Assembly,Binary,我在互联网上搜索过二进制编程,人们似乎愿意给出的唯一回答是:“你为什么要用二进制编程?”“太愚蠢了,用汇编。”“你从中什么都得不到,学习也没有意义。” 如果你是这些人中的一员,我很感激你的意见,但这并不能回答我的问题 虽然我不打算实际尝试用二进制编程,但我知道的原因是: 我有兴趣了解汇编命令背后的二进制指令 我正在设计一个生成随机二进制指令的实验。我希望它们是有效的二进制命令,并且我希望能够解释这些命令在运行时的作用 话虽如此,有人知道可以学习二进制编程的资源吗?一般来说,汇编指令和机器代码(您

我在互联网上搜索过二进制编程,人们似乎愿意给出的唯一回答是:“你为什么要用二进制编程?”“太愚蠢了,用汇编。”“你从中什么都得不到,学习也没有意义。”

如果你是这些人中的一员,我很感激你的意见,但这并不能回答我的问题

虽然我不打算实际尝试用二进制编程,但我知道的原因是:

  • 我有兴趣了解汇编命令背后的二进制指令

  • 我正在设计一个生成随机二进制指令的实验。我希望它们是有效的二进制命令,并且我希望能够解释这些命令在运行时的作用


  • 话虽如此,有人知道可以学习二进制编程的资源吗?

    一般来说,汇编指令和机器代码(您称之为二进制代码)之间存在一对一的映射。对于您关心的任何机器,您都可以在指令集体系结构文档中找到这些映射。流行的例子:

    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "add ecx, 5"
       0:   81 c1 05 00 00 00       add    ecx,0x5
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "int 0x80"
       0:   cd 80                   int    0x80
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "fmul st0, st1"
       0:   d8 c9                   fmul   st,st(1)
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "andps xmm0, xmm1"
       0:   0f 54 c1                andps  xmm0,xmm1
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "movntq [edi], mm0"
       0:   0f e7 07                movntq QWORD PTR [edi],mm0
    blackbear@blackbear-laptop:~$ 
    
  • ,尤其是第2A卷和第2B卷

  • 无论您想使用哪种体系结构,都可以找到类似的文档。您可以使用这些手册中的信息来解码给定程序的机器指令,并确定它们是如何从汇编源生成的,或者,如果您愿意,也可以手工组装您自己的程序。

    指令集手册非常有用,并且假定您具备一定程度的计算机硬件体系结构知识。以下是一些示例文档:

    手臂:

    英特尔:


    SPARC V9:

    以下是我学习二进制代码的步骤: 1.打开命令提示符并键入“debug”作为命令

  • 在“-”后面键入“a”
  • 在汇编中开始编程(确保您使用的命令非常通用,例如移动寄存器。只执行一个命令。)
  • 不键入任何内容,完成后按enter键
  • 键入“d”查看二进制文件是什么,并交叉引用多个程序
  • 请注意,在实际的二进制程序中,您需要一个十六进制编辑器。这是我使用的一个:


    我学习更复杂的语言(如c++)的另一个想法是与汇编相同,但在十六进制编辑器中打开它。

    好的,作为一个从二进制代码时代就开始这样做的老黑客:-)

    让我试着让它更具可读性

    正如你所描述的二进制代码,它被称为机器代码

    更进一步说,CPU是硬编码的,以响应某些指令,例如(请注意,目前我手头没有任何参考资料)

    6502机器代码中的值A9表示LDA(在其他体系结构上,这可能意味着不同)

    因此,如果您在6502 CPU上工作,那么序列A920意味着使用十六进制值0f 0x20加载累加器

    根据所讨论的CPU以及指令集的编码方式,数字中的不同位将导致CPU(本质上是纯逻辑)执行不同的操作

    并且,根据制造商的规格,不同的位位置指定每个操作是什么

    例如,在arm处理器中,位30和31是分支说明符,而在6502中,它们是零页内存指示符

    基本上,二进制指令是特定于所讨论的CPU的,并且通常不可移植到另一个CPU(或任何其他智能硅设备),因此移植和编写软件通常是一项非常困难的任务,除非您对编程的芯片有非常深入的了解


    除非你在英特尔这样的公司工作,或者在芯片生产商工作,否则你现在真的没有必要知道这些。然而,如果你是一个速度迷,喜欢猛击金属并挤压每一滴性能,那么你仍然可以获得进行这种编程的工具。

    很好的答案。我只想为使用linux的用户添加一个简单的脚本,它显示任何指令的二进制表示形式。您需要一份NASM(但您可以轻松编辑它,以便它使用GAS或任何其他汇编程序)和objdump:

    echo "$1" > testProgram.asm
    nasm testProgram.asm -o testProgram.out -f elf -g
    chmod 744 testProgram.out
    objdump ./testProgram.out -d -M intel | grep ' 0:'
    rm testProgram.out testProgram.asm
    
    以下是一些例子:

    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "add ecx, 5"
       0:   81 c1 05 00 00 00       add    ecx,0x5
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "int 0x80"
       0:   cd 80                   int    0x80
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "fmul st0, st1"
       0:   d8 c9                   fmul   st,st(1)
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "andps xmm0, xmm1"
       0:   0f 54 c1                andps  xmm0,xmm1
    blackbear@blackbear-laptop:~$ ./viewOpcode.sh "movntq [edi], mm0"
       0:   0f e7 07                movntq QWORD PTR [edi],mm0
    blackbear@blackbear-laptop:~$ 
    

    谢谢你的帮助。这也是很有价值的。我感谢你的帮助。这看起来确实很有用。谢谢,这是我所知道的最快的学习方法,也是学习你需要学习的命令的最准确、最具体的方法,尽管你可能想用笔记本或文件来记下你所学的东西,而且不是所有的命令第一次都会被清除。(在本例中,请更改命令的参数并重试)首先学习使用原始二进制进行数学运算可能是个好主意。