【问题标题】:Assembly language - How it works汇编语言 - 它是如何工作的
【发布时间】:2014-10-03 23:25:36
【问题描述】:

我在学习汇编语言方面真的很陌生,并且刚刚开始深入研究它,所以我想知道你们中的一些人是否可以帮助我解决一个问题。我有一个家庭作业,它告诉我将汇编语言指令与 c 代码进行比较,并告诉我哪个 c 代码等同于汇编指令。所以这里是组装说明:

pushl %ebp // What i think is happening here is that we are creating more space for the function.
movl %esp,%ebp // Here i think we are moving the stack pointer to the old base pointer.
movl 8(%ebp),%edx // Here we are taking parameter int a and storing it in %edx
movl 12(%ebp),%eax // Here we are taking parameter int b and storing it in %eax
cmpl %eax,%edx // Here i think we are comparing int a and b ( b > a ) ?
jge .L3 // Jump to .L3 if b is greater than a - else continue the instructions
movl %edx,%eax // If the term is not met here it will return b
.L3:
movl %ebp,%esp // Starting to finish the function
popl %ebp // Putting the base pointer in the right place
ret // return

我试图根据我对此的理解将其评论出来 - 但我可能完全错了。假设其中之一等效的 C 函数的选项是:

int fun1(int a, int b)
{
unsigned ua = (unsigned) a;
if (ua < b)
return b;
else
return ua;
}
int fun2(int a, int b)
{
if (b < a)
return b;
else
return a;
}
int fun3(int a, int b)
{
if (a < b)
return a;
else
return b;
}

我认为正确的答案是 fun3 .. 但我不太确定。

【问题讨论】:

  • @Puciek:实际上,OP 确实有 cmets 显示对生成的指令的假定解释。
  • 这就像一个 PHP 开发人员从他们的编码枪中拿出所有的钱并用百分比代替它们。
  • @MartinJames:你喝醉了。去睡觉... ;)
  • @SaniHuttunen - 与其假设我无法学习这一点并且将无法通过课程,不如获得一些帮助。
  • 哇,这里有一些真正的混蛋。坚持下去,SO 通常比那更好。

标签: c assembly


【解决方案1】:

首先,欢迎来到 StackOverflow。很棒的地方,真的。

首先,让我来帮助你;很多;一大堆。

你有很好的 cmets,可以极大地帮助你和我以及其他所有人,但它们太丑了,阅读它们会很痛苦。

以下是解决此问题的方法:空白、大量空白、空白行以及将指令分组为彼此相关的小组。

更重要的是,条件跳转后插入一个空行,绝对跳转后插入两个空行。 (老把戏,可读性很好)

其次,将 cmets 排列整齐,排列整齐。它看起来好一千倍。

这是你的东西,我整理了 90 秒的文字。相信我,有了这种源代码,专业人士会尊重你一千倍......

    pushl %ebp              //   What i think is happening here is that we are creating more space for the function.
    movl %esp,%ebp          //   Here i think we are moving the stack pointer to the old base pointer.

    movl 8(%ebp),%edx       //   Here we are taking parameter int a and storing it in %edx
    movl 12(%ebp),%eax      //   Here we are taking parameter int b and storing it in %eax


    cmpl %eax,%edx          //   Here i think we are comparing int a and b ( b > a ) ?
                            //   No, Think like this: "What is the value of edx with respect to the value of eax ?"

    jge .L3                 //   edx is greater, so return the value in eax as it is

    movl %edx,%eax          //   If the term is not met here it will return b
                            //   (pssst, I think you're wrong; think it through again)

    .L3:

    movl %ebp,%esp          //   Starting to finish the function
    popl %ebp               //   Putting the base pointer in the right place
    ret                     //   return

现在,回到您手头的问题。他得到的是比较指令和相关JGE指令的“意义”。

为了在这些“学术经历”中生存下来,你需要理解一些令人困惑的东西

这个 biz,cmpl %eax,%edx 指令,是“比较”指令的一种形式

当您看到该语法时,尝试形成类似这样的想法,“...目标操作数相对于源操作数的值是多少?...”

警告:我绝对不擅长 AT&T 语法,因此欢迎任何人对此进行纠正。

无论如何,在这种特定情况下,您可以像这样表达您的想法......

"...我看到cmpl %eax,%edx 所以我认为:关于eaxedx 中的值是..."

然后你在脑海中用下一条指令的“意义”完成那句话,这是一个条件跳转。

人脑中的范式过程形成这样的句子......

"...关于eaxedx中的值大于等于,所以我跳..."

所以,如果你对ab 的位置是正确的,那么你可以做范式大脑扰码器并得到这样的东西......

"...关于b中的值,a中的值大于等于,所以我会跳..."

要掌握这一点,请注意JGEJL 的“相反意义”(即“如果小于则跳转”)

好的,现在恰好 C 中的 return 与汇编语言中的 ret 指令相关,但它不是一回事。

当 C 程序员说“...那个函数返回一个 int ...”时,他们的意思是...

  • 汇编语言子例程将在Eax 中放置一个值
  • 然后子例程将修复堆栈并将其整齐地放回原处
  • 然后子程序将执行其Ret 指令

现在又是一件令人困惑的事情。

以下这些条件跳转适用于有符号算术比较运算...

  • JG
  • JGE
  • JNG
  • JL
  • JLE
  • JNL

来了!等着把你搞砸的陷阱!

您要进行有符号或无符号比较吗???

顺便说一句,我从来没有见过有人做过类似第一个函数的事情,即将无符号数与有符号数进行比较。这合法吗?

所以无论如何,我们把所有这些事实放在一起,我们得到: 这个汇编语言例程返回a 中的值,如果它小于b 中的值,否则它返回@987654348 中的值@

这些值被评估为有符号整数。

(我想我是对的;有人检查我的逻辑。我真的一点也不喜欢那个汇编程序的语法。)

因此,无论如何,我有理由确定您不想让互联网上的人为您提供特定家庭作业问题的具体答案,所以我将由您来解决这个问题解释。

希望我已经对比较的逻辑和“意义”以及已签名和未签名的业务进行了足够多的解释,以便您可以充分利用这一点。

哦,再说一次免责声明,我总是使用 Intel 语法(例如,Masm、Tasm、Nasm 等等),所以如果我在这里有什么倒退的地方,请随时为我更正。

【讨论】:

猜你喜欢
  • 2011-09-21
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 2014-01-01
  • 2016-04-15
  • 1970-01-01
相关资源
最近更新 更多