1kka
1kka

Reputation: 77

x86 assembly addition big numbers with carry

Adding two big numbers (128bit).

SYSEXIT = 1
EXIT_SUCCESS = 0

.data
number1:
    .long 0x10304008, 0x701100FF, 0x45100020, 0x08570030
number2:
    .long 0xF040500C, 0x00220026, 0x321000CB, 0x04520031

.text
.global _start
_start:


addition:
    movl $4, %ecx
    clc
add_loop:
    movl %ecx, %edx
    decl %edx
    movl number1(,%edx,4), %eax
    movl number2(,%edx,4), %ebx
    adcl %eax, %ebx
    pushl %ebx
    loop add_loop


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

I check it under gdb using x/5wx $esp and I have always 00000001 in the beginning as 5th word, even if I change number2 for 0x1040500C, 0x00220026, 0x321000CB, 0x04520031 to prevent carry. What's wrong?

Upvotes: 0

Views: 1433

Answers (2)

Crowman
Crowman

Reputation: 25908

As Jester mentions in his answer, you're not attempting to push the value of the carry bit onto the stack, so you're not seeing it - set or otherwise - when you look for it. That 00000001 was put there before _start was called.

You can use setc to set a register or memory location to the value of the carry flag, and push that, if you want to. Here's an example, with a few changes made for 64 bit assembly:

SYSEXIT = 1
EXIT_SUCCESS = 0

        .global _start

        .section .data
number1:  .long 0x10304008, 0x701100FF, 0x45100020, 0x08570030
number2:  .long 0xF040500C, 0x00220026, 0x321000CB, 0x04520031
carryval: .long 0x00

        .section .text
_start:
        movl    $4, %ecx
        clc

add_loop:
        movl    %ecx, %edx
        decl    %edx
        movl    number1(,%edx,4), %eax
        movl    number2(,%edx,4), %ebx
        adcl    %eax, %ebx
        setc    carryval                #  Added this line
        push    %rbx                    #  Changed for 64 bit
        loop    add_loop

        movl    carryval, %eax          #  Added this line
        push    %rax                    #  Added this line

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

with gdb output:

paul@thoth:~/src/asm$ gdb ./bigint
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/paul/src/asm/bigint...done.
(gdb) b 29
Breakpoint 1 at 0x4000df: file bigint.s, line 29.
(gdb) run
Starting program: /home/paul/src/asm/bigint 

Breakpoint 1, add_loop () at bigint.s:29
29          mov     $SYSEXIT, %eax
(gdb) x/5xg $rsp
0x7fffffffe518: 0x0000000000000001  0x0000000000709014
0x7fffffffe528: 0x0000000070330125  0x00000000772000eb
0x7fffffffe538: 0x000000000ca90061
(gdb) 

and you can see that the topmost value is now set to 1, to indicate your carry bit was set.

If you change the first double word of number2 to 0x1040500C, then you'll get this:

paul@thoth:~/src/asm$ gdb ./bigint
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/paul/src/asm/bigint...done.
(gdb) b 29
Breakpoint 1 at 0x4000df: file bigint.s, line 29.
(gdb) run
Starting program: /home/paul/src/asm/bigint 

Breakpoint 1, add_loop () at bigint.s:29
29          mov     $SYSEXIT, %eax
(gdb) x/5xg $rsp
0x7fffffffe518: 0x0000000000000000  0x0000000020709014
0x7fffffffe528: 0x0000000070330125  0x00000000772000eb
0x7fffffffe538: 0x000000000ca90061
(gdb) 

showing your carry flag was not set, as expected.

Upvotes: 0

Jester
Jester

Reputation: 58762

You only store 4 words, so why do you expect the 5th one to have any specific value?

By the way, that 1 should be the number of arguments passed to your program, where the first argument is customarily the name of the program itself.

Upvotes: 1

Related Questions