/* personal notes of renzo diomedi */

~ 00001011 ~




The ADD instruction is used to add two integer values. The ADD instruction format is
add source, destination
where source can be an immediate value, a memory location, or a register.
The destination parameter can be either a register or a value stored in a memory location
No use a memory location for both the source and destination at the same time
The result of the addition is placed in the destination location.

The ADD instruction can add 8-, 16-, or 32-bit values. b (for byte), w (for word), or l (for doubleword)

examples :

addb $10, %al # adds the immediate value 10 to the 8-bit AL register
addw %bx, %cx # adds the 16-bit value of the BX register to the CX register
addl data, %eax # adds the 32-bit integer value at the data label to EAX
addl %eax, %eax # adds the value of the EAX register to itself



.section .data
data:
.int 40
.section .text
.globl _start
_start:
nop
movl $0, %eax
movl $0, %ebx
movl $0, %ecx
movb $20, %al
addb $10, %al
movsx %al, %eax
movw $100, %cx
addw %cx, %bx
movsx %bx, %ebx
movl $100, %edx
addl %edx, %edx
addl data, %eax
addl %eax, data
movl $1, %eax
movl $0, %ebx
int $0x80

(gdb) print $eax
$1 = 70
(gdb) print $ebx
$2 = 100
(gdb) print $ecx
$3 = 100
(gdb) print $edx
$4 = 200
(gdb) x/d &data
0x804909c : 110


ADD is able to use the same instruction to add both signed and unsigned integer values.

.section .data
data:
.int -40
.section .text
.globl _start
_start:
nop
movl $-10, %eax
movl $-200, %ebx
movl $80, %ecx
addl data, %eax
addl %ecx, %eax
addl %ebx, %eax
addl %eax, data
addl $210, data
movl $1, %eax
movl $0, %ebx
int $0x80

(gdb) print $eax
$1 = -170
(gdb) print $ebx
$2 = -200
(gdb) print $ecx
$3 = 80
(gdb) x/d &data
0x80490ac : 0
(gdb)




CARRY FLAG is set when an addition results in a carry condition in the binary addition (the result is larger than the maximum value allowed).
For signed integers, the OVERFLOW FLAG is used when an overflow condition is present (the resulting value is less than the minimum negative value, or greater than the maximum positive value allowed). When these flags


//prog , carry flag
.section .text
.globl _start
_start:
nop
movl $0, %ebx
movb $190, %bl
movb $100, %al
addb %al, %bl
jc over
movl $1, %eax
int $0x80
over:
movl $1, %eax
movl $0, %ebx
int $0x80

$ ./prog
$ echo $?
0 # LINUX environment

The result code is 0, indicating that the carry condition was properly detected.

If
movb $190, %bl
movb $10, %al

$ ./prog
$ echo $?
200



# oc , overflow flag
.section .data
output:
.asciz "The result is %d\n"
.section .text
.globl _start
_start:
movl $-1590876934, %ebx
movl $-1259230143, %eax
addl %eax, %ebx
jo over
pushl %ebx
pushl $output
call printf

add $8, %esp # to clear the parameters placed on the stack for the printf function.

//if parameter is qd , then
//addl $12

pushl $0
call exit
over:
pushl $0
pushl $output
call printf

add $8, %esp # to clear the parameters placed on the stack for the printf function

//if parameter is qd ,
//then addl $12

pushl $0
call exit

$ ./addtest4
The result is 0

but if
movl $-190876934, %ebx
movl $-159230143, %eax

$ ./addtest4
The result is -350107077


The ADC instruction
If you must work with extremely large signed or unsigned integers that will not fit in the doubleword data size (the maximum size that can be used with the ADD instruction), you can divide the value into multiple doubleword data elements, and perform separate addition operations on each element. To do this properly, you must detect the carry flag for each addition. If the carry flag is present, it must be carried to the next data element pair that is added:








# sub-.s
.section .data
data:
.int 40
.section .text
//.globl _start
//_start:
nop
movl $0, %eax
movl $0, %ebx
movl $0, %ecx
movb $20, %al
subb $10, %al
movsx %al, %eax
movw $100, %cx
subw %cx, %bx # -100
movsx %bx, %ebx # -100
movl $100, %edx
subl %eax, %edx # 90
subl data, %eax # -30
subl %eax, data # 70
movl $1, %eax
movl $0, %ebx
int $0x21

sub-.s ; sub-.o ; sub-.exe # windows environment



Unsigned integer multiplication using MUL
The MUL instruction is used to multiply two unsigned integers. The format for the MUL instruction is
mul source
where source can be an 8-, 16-, or 32-bit register or memory value.
the destination operand is implied.
the destination location always uses some form of the EAX register, depending on the size of the source operand. Thus, one of the operands used in the multiplication must be placed in the AL, AX, or EAX registers, depending on the size of the value.
Due to the large values that can result from the multiplication, the destination location of the MUL instruction must be twice the size of the source operand.
If the source value is 8 bits, the destination operand is the AX register, as the result is 16 bits.

Unfortunately, when multiplying a 16-bit source operand, the EAX register is not used to hold the 32-bit result. In order to be backwardly compatible with older processors, Intel uses the DX:AX register pair to hold the 32-bit multiplication result value (this format started back in the 16-bit processor days). The high-order word of the result is stored in the DX register, while the low-order word is stored in the AX register.

For 32-bit source values, the 64-bit EDX:EAX register pair is used, again with the high-order doubleword in the EDX register, and the low-order doubleword in the EAX.




# mullo
.section .data
data1:
.int 315814
data2:
.int 165432
result:
.quad 0
.section .text
#.globl _start
#_start:
nop
movl data1, %eax
mull data2
movl %eax, result
movl %edx, result+4
pushl %edx
pushl %eax
pushl $0
movl $1, %eax
movl $0, %ebx
int $0x21


C:\>gdb -q users\rnz\desktop\mullo.exe
Reading symbols from users\rnz\desktop\mullo.exe...done.
(gdb) break 1
Breakpoint 1 at 0x401000: file users\rnz\desktop\mullo.s, line 1.
(gdb) run
Starting program: C:\users\rnz\desktop\mullo.exe
[New Thread 11600.0x32dc]
Breakpoint 1, ?? () at users\rnz\desktop\mullo.s:14
14 nop
(gdb) s
15 movl data1, %eax
(gdb) s
16 mull data2
(gdb) s
17 movl %eax, result
(gdb) s
18 movl %edx, result+4
(gdb) s
19 pushl %edx
(gdb) s
20 pushl %eax
(gdb) s
(gdb) print $eax
$1 = 706134096
(gdb) print/x $eax
$2 = 0x2a16c050
(gdb) print $edx
$3 = 12
(gdb) print/x $edx
$4 = 0xc
(gdb) x/gd &result
0x402008 : 52245741648
(gdb) x/8b &result
0x402008 : 80 -64 22 42 12 0 0 0
(gdb) x/8x &result
0x402008 : 0x50 0xc0 0x16 0x2a 0x0c 0x00 0x00 0x00
(gdb)

mullo.s ; mullo.o ; mullo.exe # windows environment



Home Page