Assembly pcasm书籍示例
我是x86汇编语言的新手。我正在读一本名为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个字节的机器代码 您可以通过查看汇编器输出列表(这是
$
给出了当前地址,但是:
+7
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