问题标签 [machine-code]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 汇编如何将操作码 DIV 转换为 C 代码
嘿,我知道我一直在问很多问题.. 但在谷歌上没有太多资源,所以希望这将有助于未来尝试做类似项目的人,我也总是谷歌解决方案,但我从来没有搜索过第一页。
我看了亚历克斯发布的英特尔手册,对我来说似乎很陌生 http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer- vol-2a-2b-instruction-set-az-manual.html
所以我想我知道一个简单的DIV
操作码是如何工作的。因为它divide
毕竟是。我毫不费力地添加ADD
, SUB
,当然IMUL
有问题你们帮我解决了那个问题。似乎在难度方面DIV
属于同一类别IMUL
。
好吧,不用手册就用 OllyDbg 做自我调试测试。
我发现除法的答案总是存储在EAX
. 想通了,剩下的也留着谁知道,存放在EDX
.
研究这个算法非常重要,谁知道,有人会使用随机数除法的余数来生成从 0 到 10 的切换非常聪明。但我的问题仍然存在。
这已经很奇怪了,我从没想过被除的十六进制数会有余数,小数点甚至都不属于它们。
就像
我在想也许先得到余数……只是简单的事情。
好吧,我几乎不使用数学编程,所以对我来说有点困惑。我更像是一个将结果存储在一个字符串中然后用小数点分割的人,这就是我得到剩余部分的方式是的,我知道它很慢而且它采取了简单的方法......而且我自己反对使用字符串数学代码中的运算。
好吧..看看我放在那里的那个C代码..可能必须在临时变量中发生除法之前存储两者..EAX
或者ECX
首先执行剩余代码..然后是除法代码。我不知道。
好吧,我会看到,也许你们可以为我提供更好的答案,也许它不能在一行中完成,但也许我犯了一些错误.. 由于许多其他事情,我无法真正测试我现在所做的事情在我编译软件之前必须修复。
assembly - AMD64机器码“48 ff 25”是什么意思?
谁能告诉我以下反汇编代码中的“0x48ff25”是什么意思?
我查了AMD64架构程序员手册,但是自己真的很难找到答案……
x86 - 可以使用十六进制编辑器来编辑可执行二进制文件中的指令吗?
如果我有一个包含已编译 C 代码的二进制可执行文件,我是否可以使用十六进制编辑器来编辑该二进制文件并将特定指令更改为另一个指令,例如nop
或jmp
?我如何知道要更改的指令的偏移量?
是的,这是出于教育目的。
dos - 我如何弄清楚可执行文件的作用?
我有一组简短的机器指令(160 字节),但我不知道它的作用。
我在 Mac 上,我在 GDB 反汇编程序下运行它,结果如下:
我对汇编程序知之甚少,但有些命令看起来很有趣(比如rex.RXB, rex.WB, rex.B
)。所以经过一番谷歌搜索后,我发现这个命令告诉我它是一个 DOS 可执行文件:
- 有没有可以反汇编DOS可执行文件的程序?
如果没有,我会尝试手动反汇编,因为只有 160 个字节。但是,我需要参考每个字节的含义。例如
DOS机器代码指令是否有这样的参考?
我还能如何找出程序的作用?
更新:
在 IGOR 的一个很好的建议之后,我使用不同的程序反汇编了代码。但是,仍然有一些不好的说明:
- 任何想法为什么它说
(bad)
?
x86 - 机器代码如何访问子程序调用的参数?
运行程序时,您可以传递参数,例如
在 C 中,您可以通过查看来访问这些参数argv
,
这将如何翻译成汇编/x86机器代码?你将如何访问给你的变量?系统将如何为您提供这些变量?
我对汇编很陌生,它使您只能访问寄存器和绝对地址。我很困惑如何访问参数。系统是否为您将参数预加载到专用寄存器中?
x86 - 在 x86 汇编中,如何在不进行比较操作的情况下设置零标志 (ZF)?
我有一小段(x86)程序集,我试图弄清楚它的作用。
它看起来像是在循环,直到“JNE”评估为假,即零标志 = 0。(可能将数字 1、2、3 ......放入堆栈??)
从我对装配的简短调查(我是新手)来看,你通过比较操作(CMP)设置了零标志,但我没有看到比较操作。
那么,在什么情况下它会跳出这个循环呢?
assembly - Homoiconic 和“不受限制”的自我修改代码 + lisp 真的是自我修改吗?
我承认我对 Lisp 的了解非常少。但是我对这门语言非常感兴趣,并计划在不久的将来开始认真学习它。我对这些问题的理解无疑是有缺陷的,所以如果我说了什么明显错误的话,请评论和纠正我,而不是投反对票。
真正的同音和自修改语言
我正在寻找支持 Homoiconicity(代码与数据具有相同的表示形式)和无限制的自我修改(无限制意味着您可以更改正在运行的代码的各个方面,而不仅仅是发出新代码或更改函数指针/代表。)
到目前为止,我发现只有三个例子符合这个标准:
- 机器码。Homoiconic 因为一切都是数字。可不受限制地修改,因为它包含指针,可用于操作任何内存地址,无论该地址是否包含代码或数据。
- 马尔堡。与机器代码相同的推理。每条指令在执行后都会自我修改
- 脱氧核糖核酸。不是编程语言,但仍然很有趣。它不像机器代码那样自我修改;实际指令+数据被修改到位的地方。然而,它是自我复制的,可以根据之前的状态变异/进化(辐射等副作用时不时地把它搞砸)。无论如何,这只是一种间接的自我修改方式。简而言之,DNA可以自我修改,但它是通过在其整体中复制自身以及相关突变来实现的。DNA 的物理串是“不可变的”。
为什么 Lisp 不在此列表中
Lisp 不在该列表中,因为在我看来 Lisp几乎是同音异形的,并且只支持受限的自我修改。你可以做类似的事情
这将做同样的事情
在第一个版本中(+ 1 2 3)
是原始代码,而在第二个版本中是数据。通过假设这个陈述的真实性,可以说 Lisp 甚至不是 homiconic。代码具有与数据相同的表示形式,因为它们都是列表/树/S 表达式。但是,您必须明确标记这些列表/树/S 表达式中的哪些是代码,哪些是对我来说是数据,这一事实似乎表明 Lisp 毕竟不是 homiconic。这些表示非常相似,但它们在微小的细节上有所不同,您必须实际说明您是在处理代码还是数据。这绝不是一件坏事(事实上其他任何事情都是疯狂的),但它突出了 Lisp 和机器代码之间的区别。在机器代码中,您不必明确标记哪些数字是指令,哪些是指针,哪些是数据。
这是反对不受限制的自我修改的更有力的案例。当然,您可以获取代表一些代码的列表并对其进行操作。例如改变
到
然后你运行它eval
。但是当你这样做时,你只是在编译一些代码并运行它。您不是在修改现有代码,您只是在发布和运行新代码。C# 可以使用表达式树做同样的事情,即使格式不太方便(这是由于 C# 代码对其 AST 具有不同的表示形式,而不是 Lisp,它是它自己的 AST)。您是否真的可以获取整个源文件并在整个源文件运行时开始修改它,对源文件所做的更改会对程序行为产生实时影响?
除非有某种方法可以做到这一点,否则 Lisp 既不是 homiconic 也不是自我修改的。(为了推迟对定义的争论,Lisp 不像机器代码那样同音或自我修改。)
使 Lisp Homoiconic/无限制地自我修改的方法
我可以看到 3 种潜在的方法来使 Lisp 像机器代码一样具有同义性/可自我修改。
- 非冯诺依曼架构。如果有人可以发明一些惊人的假设机器,其中程序的最低级别表示是可以直接执行的 AST(无需进一步编译)。在这样的机器上,AST 既代表可执行指令,也代表数据。不幸的是,问题还没有解决,因为 AST 仍然必须是代码或数据。eval 函数的出现不会改变这一点。在机器代码中,您可以根据需要在代码和数据之间来回切换。而使用 eval 和 Lisp 后,一旦您将某个列表从数据“评估”到代码并执行了它,就无法再次将该列表作为数据取回。实际上,该列表已永远消失,并已被其价值所取代。我们会遗漏一些关键的东西,这恰好是指针。
- 列出标签。如果要求每个列表也具有唯一标签,则可以通过对具有给定标签的列表运行函数来进行间接自我修改。结合延续,这最终将允许在与机器代码相同的意义上自我修改代码。标签等同于机器代码内存地址。例如,考虑一个 Lisp 程序,其中 AST 的顶部节点具有标签“main”。然后,在 main 中,您可以执行一个函数,该函数接受一个标签、一个整数、一个原子,并将原子复制到列表中,其标签与提供给函数的标签相匹配,位于整数指定的索引处。然后只需在 main 上调用当前的继续。你去,自我修改代码。
- Lisp 宏。我没有花时间去理解 Lisp 宏,它们实际上可能完全符合我的想法。
第 1 点与第 2 点相结合将产生一个完全自我修改的 Lisp。前提是可以生产所描述的神奇的 Lisp 机器。2. 单独可以产生一个自我修改的 Lisp,但是在冯诺依曼架构上的实现可能非常低效。
问题
- 除了机器码、dna 和 malbolge 之外,还有什么语言可以进行完全的自我修改并且是同音的?
- (如果您在上面的文字中做了一个 tl;dr,请不要费心回答)。lisp 真的是谐音+自我修改吗?如果你这么说,你能准确引用我的论点中我误入歧途的地方吗?
附录
具有不受限制的自我修改但没有同音性的语言
- 集会。该代码使用单词而不是数字,因此失去了同义性,但它仍然具有指针,它保留了对内存的完全控制并允许不受限制的自我修改。
- 任何使用原始指针的语言。例如 C/C++/Objective C。与 Assembly 相同的参数
- 包含虚拟指针的 JIT 语言。例如在不安全的上下文中运行的 C#/.net。与大会相同的论点。
其他可能相关/有趣的概念和语言:Lisp、Ruby、Snobol、Forth 和它的编译时元编程、Smalltalk 和它的反射、无类型的 lambda 演算及其属性,即一切都是函数(这意味着假设我们可以发明一台直接执行 lambda 演算的机器,lambda 演算将是同形的,而 Von Neumann 机器代码在该机器上运行时不会。[并且 Godels theorem 将是可执行的。哈哈,可怕的想法:P])
machine-code - 机器码跳转目的地计算
好的,所以我需要挂钩一个程序,但要做到这一点,我将复制指令E8 <Pointer to Byte Array that contains other code>
。这样做的问题是,当我汇编时Call 0x100
,E8 FD
我们知道 E8 是调用指令,所以 FD 必须是目的地,那么汇编器如何将目的地从 0x100 带到 FD 中?谢谢,布拉德利-Imcept
c++ - 如何在标准 C/C++ 代码中包含和翻译自定义指令/扩展以保持高性能
我正在为 FPGA 和 ASIC 开发通用图像处理核心。这个想法是将标准处理器与它连接起来。我遇到的问题之一是如何“编程”它。让我解释一下:核心有一个用于我的“自定义”扩展的指令解码器。例如:
还有更多类似的。该操作由处理器通过总线发送到内核,使用处理器进行循环、非向量操作等,如下所示:
程序是用 C/C++ 编写的。核心只需要指令本身,机器码
- 操作码 = vector_add = 0x12h
- register_src_1 = v0 = 0x00h
- register_src_2 = v1 = 0x01h
register_dst = v2 = 0x02h
机器码 = opcore | v0 | v1 | v2 = 0x7606E600h
(或其他任何东西,只是不同字段的连接以构建二进制指令)
一旦通过总线将其发送到内核,内核就能够使用专用总线从内存中请求所有数据,并在不使用处理器的情况下处理所有事情。最大的问题是:我怎样才能将前面的指令翻译成它的十六进制表示?(通过公共汽车发送不是问题)。想到的一些选择是
- 运行解释代码(在处理器中运行时转换为机器代码)-> 非常慢,即使使用某种内联宏
- 使用外部自定义编译器编译自定义部分,从外部存储器加载二进制文件并使用一些独特的指令将其移动到核心 --> 难以阅读/理解源代码,SDK 集成不佳,如果代码非常分段,则部分过多
- JIT 编译 --> 就为了这个复杂?
- 扩展编译器 --> 一场噩梦!
- 一个连接到自定义核心的自定义处理器来处理所有事情:循环、指针、内存分配、变量... --> 工作量太大
问题是关于软件/编译器的,但对于那些对该主题有深入了解的人来说,这是 FPGA 中的 SoC,主处理器是 MicroBlaze,IP 核采用 AXI4 总线。
我希望我解释正确......提前谢谢!
performance - 什么 switch 语句产生效率最低的机器代码?
我的一个测试中有一个问题要求我回答哪个 switch 语句产生的机器代码效率最低。可能的答案是 O4、O1、O2 或 O3。我不知道那些应该是什么意思。