无法在32位代码中递增寄存器

时间:2017-05-09 20:16:22

标签: assembly x86 nasm increment intel

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

我正在尝试编写一个程序,它从内存中添加(带进位)两个数字,一块一块地(32位)并将部分和写入堆栈。不幸的是,不确定为什么,循环计数器在inc %ecx之后不会增加。 (我已经在gdb中进行了测试,%ecx甚至在0指令之后仍然保持inc

我为英特尔架构写作,但使用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

如果你还能解释它为什么会发生以及将来如何避免这个问题,我真的很感激(我还在学习,你可以看到)。另外,如果你看到其他一些错误,请告诉我。提前谢谢。

1 个答案:

答案 0 :(得分:0)

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

.code32

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

as --32 code.s

现在为什么跳过inc?在x86处理器上,32位模式与64位模式非常相似,因此大多数指令都做同样的事情。大多数情况下,引入了一组新的前缀来区分32位和64位指令。由于这些新前缀没有可用的操作码,因此将操作码40改为4f(意为inc r32dec r32)。 incdec指令仍以不同的双字节编码方式提供。因此,处理器“跳过”了您的inc,而是更改了下一条指令。

除非你做了很奇怪的事情(比如写一个bootloader),否则你永远不需要.code32指令。忘了它存在。请注意,您不应使用int $0x80以64位代码进行系统调用,因为这些系统调用只接受32位指针。在64位代码中,使用syscall进行系统调用,但请注意系统调用号和调用约定都不同。