返回64位负数IA32汇编

时间:2015-10-16 19:40:08

标签: assembly x86

我正在大学课程中学习IA32位汇编,我很难回复64位数字。我必须做(var8 + var16) - (var32 + var32x),并以64位int显示结果。我得到了正确的结果,但数字应为负数。你能看一下这个并给我一些关于我做错什么的见解吗?

谢谢

继承我的代码:

function.h:

long function(void);

function.s:

.section .data
.global var8
.global var16
.global var32
.global varx32
.global res
.section .text
.global function

function:

movl $0, %eax
movl $0, %edx   

movl var32, %eax
movl varx32, %edx

addl %edx, %eax


movl $0, %ebx
movw var16, %bx

movl $0, %ecx
movb var8, %cl

addl %ebx, %ecx

sbb %ecx, %eax



movl %eax, res  



ret

的main.c

#include <stdio.h>
#include "function.h"
char var8= 127;
short var16=32767; 
int var32=2147483647, varx32=2147483647;
long long res=0;


int main(void) {
printf("Value A: %d\nValue B: %d\nValue C: %d\nValue D: %d\n", var8, var16, var32, varx32);
function();

printf("\n%lld\n", res);
return 0;
}

1 个答案:

答案 0 :(得分:0)

不要忘记符号位。现在你只能用正数来计算。如果使用负值处理,则术语的结果可能会溢出32位寄存器。因此,将此结果存储在两个32位寄存器中。

res是一个64位变量(long long),即8个字节。您将%eax存储到res - 只有4个字节。高4个字节保持为空(long long res=0;)。因此结果将始终为正,因为符号位(最高字节的最高位)为空。

TL; DR - 尝试理解以下功能:

function:

    pushl %ebx                  # to be preserved by the callee (https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl)        

    movswl var16, %eax          # = `movsx eax, var16` (https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html)
    movsbl var8, %edx           # = `movsx edx, var8` (https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html)
    addl %edx, %eax
    movl $0, %edx
    adcl $0, %edx               # EDX:EAX Result of first term

    movl var32, %ebx
    addl varx32, %ebx
    movl $0, %ecx
    adcl $0, %ecx               # ECX:EBX Result of second term

    subl %ebx, %eax             # EDX:EAX = EDX:EAX - ECX:EBX
    sbbl %ecx, %edx

    movl %eax, res              # Store EDX:EAX to `res`
    movl %edx, res + 4

    popl %ebx                   # return EBX unchanged
    ret

我改变了计算顺序和使用过的寄存器。按照惯例,函数的返回值存储在EAX(32位)或EDX:EAX(64位)中。如果您决定将function的返回类型从long(32位环境中的32位)更改为long long(64位),那么您还可以使用我的返回值功能