【问题标题】:Cannot increment register in 32 bit code不能在 32 位代码中增加寄存器
【发布时间】:2017-05-09 20:16:22
【问题描述】:

我有一个相当愚蠢的问题,但我在任何地方都找不到解决方案。

我正在尝试编写一个程序,该程序将内存中的两个数字(带进位)逐个(32 位)相加,并将部分和写入堆栈。不幸的是,不知道为什么,循环计数器在inc %ecx 之后没有增加。 (我已经在 gdb 中测试过,%ecx 甚至在 inc 指令之后也保持在 0)。

我为 Intel 架构编写,但使用的是 AT&T 语法(我在这里别无选择)。

.code32

SYSEXIT = 1
EXIT_SUCCESS = 0

.align 32
.data
nr1:
    .long 0xF0000111, 0x000B0000
nr2:
    .long 0x10000333, 0x000A000F
size:
    .long 0x00000002

.text
.global _start
_start:
mov $0, %ecx                 #initialization of counter
movl size(,%ecx,4), %edi     #moving size (amount of 32-bit pieces) to %edi

addition:
movl nr1(,%ecx,4), %eax    #moving one piece 
movl nr2(,%ecx,4), %ebx    #(from address of nr1 + (value of %ecx * 4 bytes)

adcl %ebx, %eax                 #add with carry
push %eax                       #push the result

inc %ecx                        #increment counter
cmp %edi, %ecx                  #compare %edi (==2) with counter (%ecx)
je overflow                     # if %edi == %ecx
jmp addition                    # else back to addition loop

overflow:   #in case when last sum had an overflow (CF==1)
mov $0, %eax                   
adcl $0, %eax
push %eax

end:
mov $SYSEXIT, %eax
mov $EXIT_SUCCESS, %ebx
int $0x80

如果您还可以解释它发生的原因以及将来如何避免该问题,我将不胜感激(如您所见,我仍在学习)。另外,如果您发现其他错误,请告诉我。提前致谢。

【问题讨论】:

    标签: assembly x86 nasm increment intel


    【解决方案1】:

    您似乎在 64 位系统上组装您的代码。因此,汇编器默认为 64 位二进制文​​件。这种二进制文件中的所有代码都将作为 64 位代码执行。指令

    .code32
    

    使汇编器发出 32 位代码,但不会改变处理器解释指令的方式;它会将您的代码解释为 64 位代码。要让汇编器生成一个 32 位目标文件(处理器会将其解释为 32 位代码),您需要在命令行上传递一个特殊开关:

    as --32 code.s
    

    现在为什么会跳过inc?在 x86 处理器上,32 位模式与 64 位模式非常相似,因此大多数指令执行相同的操作。大多数情况下,引入了一组新的前缀来区分 32 位和 64 位指令。由于这些新前缀没有可用的操作码,因此操作码 404f(意思是 inc r32dec r32)被重新利用。 incdec 指令仍可用于不同的两字节编码。出于这个原因,处理器“跳过”了您的inc,而是更改了下一条指令。

    除非您正在做非常奇怪的事情(例如编写引导加载程序),否则您永远不需要.code32 指令。忘记它的存在。请注意,您不应使用int $0x80 在 64 位代码中进行系统调用,因为这些系统调用仅接受 32 位指针。在 64 位代码中,系统调用使用syscall,但请注意系统调用号和调用约定不同。

    【讨论】:

    • 正如我在另一个答案下所写的那样,它确实有帮助(以及在删除 .code 32 后修复 push 的操作数)。感谢您的解释和提示,应该可以为我节省一些麻烦。
    • @Newb 由于您的老师似乎教 32 位汇编,如果您只是使用 --32 标志将汇编为 32 位程序可能会更好。总是乐于提供帮助!
    • 我可能会弄乱那个标志,但现在,我很高兴我有一些工作可以依靠,以防出现问题/我没时间了。
    猜你喜欢
    • 2014-12-17
    • 2014-11-18
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 2015-01-21
    相关资源
    最近更新 更多