2

我是 x86 汇编语言的新手。我正在阅读一本名为 pcasm 的书,我想知道是否有人可以帮助我更好地理解这个代码示例(这是书中的部分代码):

32    mov    ebx, input2
33    mov    ecx, $ + 7
34    jmp    short get_int
35
36    mov    eax, [input1]


64    get_int:
65        call   read_int
66        mov    [ebx], eax
67        jmp    ecx

现在,我的理解是$给出当前地址,但是:

  1. 为什么+ 7
  2. 我该如何计算呢?
  3. 如果我使用jmp near get_int(4 个字节)和jmp near word get_int(2 个字节),这个数字会怎样?第二种语法正确还是应该正确jmp word get_int

谢谢

4

2 回答 2

2

是的,我认为卡特博士正在研究“呼叫”的作用......以及为什么我们使用“呼叫”而不是这种迂回的方式。

如果您在命令行中添加“-l myfile.lst”,Nasm 将使您成为一个列表文件。

立即“jmp”的语法是“jmp short”和“jmp near”。(还有“jmp far”,但它做了一些不同的事情——在 32 位代码中通常不有用)。多年来,Nasm 在这方面的行为发生了变化——如果你刚刚说“jmp”,旧的 Nasm 过去会默认给你“jmp near”——如果合适的话,新的 Nasm 将使用“jmp short”。您可能需要使用“jmp strict near”在新的 Nasm 中实际获得“near jmp”(或在命令行上使用“-O0” - 大写“o”,零 - 以关闭优化)。这是破坏现有代码的事情。硬编码偏移“+7”是“不可维护”的代码。我确信 Carter 博士是在说明问题,而不是敦促您以这种方式编写代码!

作为此代码和“call/ret”之间的“中间人”,尝试在您希望子例程返回的位置放置一个标签,并将其放入 ecx。如果你想从多个地方“不调用”这个子程序,你必须做“ret_addr1:”、“ret_addr2:”等。当然,你不能改变子程序中的ecx!使用“call/ret”,我们不必弄乱堆栈——通常是一个更好的权衡。

最好的,弗兰克

于 2012-07-23T06:13:31.127 回答
2
  1. 使用示例代码+ 7是因为大概为源代码行 33 和 34 组合生成了 7 个字节的机器代码。

  2. 您可以通过查看汇编器输出列表(您可能必须在汇编器中打开它)并计算字节数来计算所需的偏移量。

  3. 如果您使用汇编为不同数量的机器代码字节的指令,则所需的偏移量将不同。您必须在您的环境中尝试它才能看到您需要什么。

于 2012-07-23T01:07:31.567 回答