【问题标题】:x86 assembly language homework probx86 汇编语言作业问题
【发布时间】:2013-08-11 19:48:27
【问题描述】:

我在作业问题上需要帮助。我应该弄清楚这段代码运行后edx 的值是多少。

0x40106e    <main+30>:      mov    $0x1,%edx
0x401073    <main+35>:      mov    $0x8,%ecx
0x401078    <main+40>:      test   %ecx,%ecx
0x40107a    <main+42>:      jg     0x40107e <main+46>
0x40107c    <main+44>:      jmp    0x40108a <main+58>
0x40107e    <main+46>:      lea    (%ecx,%ecx,1),%eax
0x401081    <main+49>:      lea    (%eax,%edx,1),%eax
0x401084    <main+52>:      lea    0xffffffff(%eax),%edx
0x401087    <main+55>:      dec    %ecx
0x401088    <main+56>:      jmp    0x401078 <main+40>
0x40108a    <main+58>:      // endpoint

既然是家庭作业,我真的不想知道答案,而是想知道如何弄清楚。我在弄清楚循环时遇到了麻烦,但我想我明白了。我认为test %ecx,%ecx 循环直到%ecx 减为0。对吗?真正让我感动的是lea 的所有东西。我不知道那是在做什么。

【问题讨论】:

标签: assembly x86


【解决方案1】:

testjg 是对的;它确实会循环直到ecx 为零。

lea

我对 AT&T 语法不是很熟悉,所以我将使用 Intel 语法(我觉得它更直观)。我希望它仍然可以理解。 (主要区别之一是 Intel 语法将目标放在首位。)

一些指令可以让你从一个地址加载一个值:

mov eax, [esi]  ; load a DWORD from the address in ESI

您可以更改这些以添加偏移量:

mov eax, [esi + 4]  ; load a DWORD from four bytes after the address in ESI

允许某些寄存器、比例和偏移的组合:

mov eax, [esi + ecx * 4 + 16]  ; load a DWORD from (ECX * 4 + 16) bytes after the
                               ; address in ESI

这样比较方便;无需手动计算有效地址。

lea 代表“加载有效地址”。本质上,它可以让你做这样的事情:

lea eax, [esi + ecx * 4 + 16]

它不是将值加载到内存中的那个位置,而是计算地址;换句话说:

EAX = ESI + ECX * 4 + 16

上面的 lea 指令汇编为 4 个字节。相比之下,对我来说最明显的方式:

mov eax, ecx
shl eax, 2
add eax, esi
add eax, 16

…组装成 14 个字节。

【讨论】:

  • 那么这里发生了什么:lea 0xffffffff(%eax),%edx
  • @user2672982:在 Intel 语法中,应该是 lea edx, [eax + 0xFFFFFFFF]0xFFFFFFFF 是负数,所以它与lea edx, [eax - 1] 相同。根据上面的解释和我的解释,您可以证明它将EDX 设置为比EAX 小一。
  • 哦,我明白了我的问题是我不记得 0xFFFFFFFF 是负 1。我以为这是一个巨大的数字。
【解决方案2】:

正如 icktoofay 所解释的,lea 指令会将edx 寄存器设置为eax - 1。让我们一步一步地浏览整个代码。

前两行将立即值移动到寄存器,因此edx 等于1ecx 设置为8

test 指令位于此处循环的开头,并与紧随其声明循环执行条件之后的指令一起。 test 指令影响很多标志,但由于条件跳转是jg,我们将只关注ZFOFSFjg 仅在 ZF=0SF=OF 时分支。现在

  • ZF 将为零,直到 ECX!=0
  • OF 将始终为零,SF 也是如此,因为8 在二进制补码中大于零(更准确地说,8 的最高有效位是 0)。

第一条lea 指令将eax 设置为2*ecx。第二个也是最后一个 leas 将 eax 添加到 edx 并减少它。最后,ecx 递减,指令指针指向循环的开始。

象征性地写出来:

sum(8, n = 1, n*2 -1) + 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2023-03-25
    • 2012-11-27
    • 2015-04-05
    • 1970-01-01
    • 2011-02-15
    • 2017-01-03
    相关资源
    最近更新 更多