Assembly pcasm书籍示例

Assembly pcasm书籍示例,assembly,x86,nasm,Assembly,X86,Nasm,我是x86汇编语言的新手。我正在读一本名为pcasm的书,我想知道是否有人能帮助我更好地理解这个代码示例(这是书中的部分代码): 现在,据我所知,$给出了当前地址,但是: 为什么+7 我怎么计算呢 如果我在get_int附近使用jmp(4个字节)和在word get_int附近使用jmp(2个字节),数字会发生什么变化?第二个语法正确吗?还是应该是jmp word get_int 谢谢 示例代码使用+7,因为可能为源代码行33和34组合生成了7个字节的机器代码 您可以通过查看汇编器输出列表(这是

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

现在,据我所知,
$
给出了当前地址,但是:

  • 为什么
    +7
  • 我怎么计算呢

  • 如果我在get_int附近使用
    jmp(4个字节)和在word get_int附近使用
    jmp(2个字节),数字会发生什么变化?第二个语法正确吗?还是应该是
    jmp word get_int
  • 谢谢

  • 示例代码使用
    +7
    ,因为可能为源代码行33和34组合生成了7个字节的机器代码

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

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

  • 示例代码使用
    +7
    ,因为可能为源代码行33和34组合生成了7个字节的机器代码

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

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


  • 是的,我想卡特博士正在研究“呼叫”的作用。。。为什么我们用“呼叫”而不是用这种方式

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

    立即“jmp”的语法是“jmp short”和“jmp near”。(也有“jmp far”,但它做了一些不同的事情——在32位代码中并不经常有用)。在这方面,Nasm的行为在过去几年中已经发生了变化——旧的Nasm在默认情况下会给你“jmp-near”,如果你只说“jmp”,新的Nasm会在合适的时候使用“jmp-short”。您可能需要使用“jmp strict near”在新Nasm中实际获得“near jmp”(或者在命令行上使用“-O0”-大写字母“o”,零-来关闭优化)。这是一种破坏现有代码的行为。硬编码偏移量“+7”为“不可维护”代码。我相信卡特博士是在说点什么,不是在敦促你用这种方式编码

    作为此代码和“call/ret”之间的“中间”,请尝试将标签放在希望子例程返回的位置,并将其放在ecx中。如果您想从多个位置“不调用”此子例程,则必须执行“ret_addr1:”、“ret_addr2:”等操作。当然,您不必更改子例程中的ecx!使用“call/ret”时,我们不能把堆栈搞得一团糟,这通常是一个更好的权衡

    最好的,
    弗兰克

    是的,我想卡特博士正在努力实现“呼叫”的功能。。。为什么我们用“呼叫”而不是用这种方式

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

    立即“jmp”的语法是“jmp short”和“jmp near”。(也有“jmp far”,但它做了一些不同的事情——在32位代码中并不经常有用)。在这方面,Nasm的行为在过去几年中已经发生了变化——旧的Nasm在默认情况下会给你“jmp-near”,如果你只说“jmp”,新的Nasm会在合适的时候使用“jmp-short”。您可能需要使用“jmp strict near”在新Nasm中实际获得“near jmp”(或者在命令行上使用“-O0”-大写字母“o”,零-来关闭优化)。这是一种破坏现有代码的行为。硬编码偏移量“+7”为“不可维护”代码。我相信卡特博士是在说点什么,不是在敦促你用这种方式编码

    作为此代码和“call/ret”之间的“中间”,请尝试将标签放在希望子例程返回的位置,并将其放在ecx中。如果您想从多个位置“不调用”此子例程,则必须执行“ret_addr1:”、“ret_addr2:”等操作。当然,您不必更改子例程中的ecx!使用“call/ret”时,我们不能把堆栈搞得一团糟,这通常是一个更好的权衡

    最好的,
    Frank

    这似乎是一种迂回的方式,可以手动执行
    调用
    指令可以为您执行的操作。在现实世界中,没有人会这样做,你只需要使用
    call
    ret
    @Greg Hewgill-是的,这与
    call
    ret
    做相同的事情,但这只是本书中的一个例子(pcasm),我试图理解它的所有例子。但是你完全正确。这似乎是手动执行
    调用
    指令可以为你做的事情的一种迂回方式。在现实世界中,没有人会这样做,你只需要使用
    call
    ret
    @Greg Hewgill-是的,这与
    call
    ret
    做相同的事情,但这只是本书中的一个例子(pcasm),我试图理解它的所有例子。但你完全正确。@Greg Hewgill-
    +7
    不是因为调用read_int
    (1字节)、
    mov[ebx]、eax
    (4字节)和
    jmp ecx
    (1字节)==6字节和+1是因为我们想到达第36行,还是我的假设完全错误?@markfw:No,7不取决于子例程本身的长度。第33行将所需的“下一个”地址(看起来是第36行,这是7的所在)加载到
    ecx
    寄存器中。然后它跳到
    get_int
    ,它做任何事情,然后跳回到
    ecx
    @Greg Hewgill-
    +7
    中包含的任何地址,不是因为
    调用read_int
    (1字节)、
    mov[ebx]、eax
    (4字节)和
    jmp ecx
    (1字节)==6b吗
    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