Reputation: 77
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
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
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