Sign extension in assembly IA32

639 views Asked by At

I'm new to assembly and I'm using IA32 architecture. I'm trying code a .s function that produces the following operation: C + A - D + B

  • A is an 8-bit variable
  • B is a 16-bit variable
  • C and D are both 32-bit variables

The function should return a 64-bit value that must be printed in C and I can't figure this out.

I am trying this and it works for the tests of positive numbers, but when I'm working with negative numbers it doesn't work and I can't figure out the reason.

My function sum_and_subtract.s:

.section .data

.global A
.global B
.global C
.global D

.section .text
.global sum_and_subtract

# short sum_and_subtract(void)

sum_and_subtract:

#prologue 
    pushl %ebp 
    movl %esp, %ebp
    
    pushl %ebx
    
#body of the function

    movl $0, %eax # clear eax   
    movl C, %eax
    movl $0, %ecx
    movb A, %cl
    
    addl %ecx, %eax
    movl $0, %edx
    movl D, %edx
    subl %edx, %eax
    movl $0, %ebx
    movw B, %bx
    addl %ebx, %eax
        
    movl $0, %edx
    adcl $0, %edx
    
    cdq
#epilogue

fim:

    popl %ebx
    
    movl %ebp, %esp
    popl %ebp
    ret

An correct example is:

  • A = 0, B = 1, C = 0, D = 0; Expected = 1 -> Result = 1 and It works for this example

The error appears when:

  • A = 0, B = 0, C = 0, D = 1; Expected = -1 -> Result = 256

After seeing your comments I forgot to write my main code where I print my long long result.

main.c :

#include <stdio.h>
#include "sum_and_subtract.h"   

char A = 0;
short B = 0;
long C = 0;
long D = 1;

int main(void) {
    
    printf("A = %d\n", A);
    printf("B = %hd\n", B);
    printf("C = %ld\n", C);
    printf("D = %ld\n", D);

    long long result = sum_and_subtract();
    
    printf("Result = %lld\n", result);
    
    return 0;

}

Here it is.

I have this other file sum_and_subtract.h

long long sum_and_subtract(void);
1

There are 1 answers

1
0___________ On

I would follow the C compiler:

doit:
        movsbl  A(%rip), %eax
        movswl  B(%rip), %edx
        addl    C(%rip), %eax
        subl    D(%rip), %eax
        addl    %edx, %eax
        cltq
        ret
        movsx   eax, BYTE PTR A[rip]
        movsx   edx, WORD PTR B[rip]
        add     eax, DWORD PTR C[rip]
        sub     eax, DWORD PTR D[rip]
        add     eax, edx
        cdqe
        ret

It "prints" -1

It is rather a comment so do not UV. Feel free to DV

The complete code with print: https://godbolt.org/z/3a9YMo

And with the printing code: https://godbolt.org/z/KT8YWT