/*personal notes of renzo diomedi*/

~ 00000001 ~








GDB -q prog # in mingw windows also without q .exe file.obj
break *_start+1 # in mingw windows also simply start 1
run
print or print/x or print/t $register # decimal , hex , binary
next or step or s
x/n or x/nx or x/nd or x/nt &label # n hex , n hex , n decimal , n binary
info reg , info registers , to show values in the registers



The .equ directive is used to set a constant value to a symbol that can be used in the text section:
.equ factor, 3

To reference the static data element, you must use a dollar sign before the constant declared
movl $LINUX_SYS_CALL, %eax
moves the value assigned to the LINUX_SYS_CALL symbol to the EAX register.



bss section

Defining data elements in the bss section is somewhat different from defining them in the data section. Instead of declaring specific data types, you just declare raw segments of memory that are reserved for whatever purpose you need them for.
The GNU assembler uses two directives to declare buffers
Directive
.comm //Declares a common memory area for data that is not initialized
.lcomm //Declares a local common memory area for data that is not initialized
While the two sections work similarly, the local common memory area is reserved for data that will not be accessed outside of the local assembly code. The format for both of these directives is
.comm symbol, length
where symbol is a label assigned to the memory area, and length is the number of bytes contained in the memory area,
.section .bss
.lcomm buffer, 10000
These statements assign a 10,000-byte memory area to the buffer label. Local common memory areas cannot be accessed by functions outside of where they were declared (they can’t be used in .globl directives).
One benefit to declaring data in the bss section is that the data is not included in the executable program. When data is defined in the data section, it must be included in the executable program, since it must be initialized with a specific value. Because the data areas declared in the bss section are not initialized with program data, the memory areas are reserved at runtime, and do not have to be included in the final program

To wiew the size of the program:
as -o prog.o prog.s
ld -o prog prog.o
ls -al prog //generates the output that shows the number of bytes

.section .bss
.lcomm buffer, 10000 //directive of .bss
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80

10000 bytes reserved are not increased in the size of the executable program file
prog.bss

instead

.section .data
buffer:
.fill 10000 //directive of .data , creates one byte per field, and fill it with zeros.
// instead the directive .bytes declares a value
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80

now the size of the executable program file is increased of 10000 bytes.
prog.data





movl %eax, %ebx
movw %ax, %bx
movb %al, %bl

An immediate data element to a general-purpose register
An immediate data element to a memory location
A general-purpose register to another general-purpose register
A general-purpose register to a segment register
A segment register to a general-purpose register
A general-purpose register to a control register
A control register to a general-purpose register
A general-purpose register to a debug register
A debug register to a general-purpose register
A memory location to a general-purpose register
A memory location to a segment register
A general-purpose register to a memory location
A segment register to a memory location


//rtm
.section .data
ml:
.long 545
.section .text
.globl _start
_start:
nop
movl $444, %eax
movl %eax, ml #the previous of ml value is deleted and replaced
movl $1, %eax
movl $0, %ebx
int $0x80


$ gdb -q rtm
(gdb) break *_start+1
Breakpoint 1 at 0x8048075: file rtm.s line 9.
(gdb) run
Starting program: /...........
Breakpoint 1, _start () at rtm...
9 movl $444, %eax
(gdb) x/d &ml
0x804908b: 545
(gdb) s # net instruction
12 movl %eax, ml
(gdb) s
13 movl $1, %eax
(gdb) x/d &ml
0x804908b: 444
(gdb) x/t &ml
0x804908b: 000000000000000000000110111100
(gdb) x/x &ml
0x804908b: 0x000001bc
(gdb)


(gdb) x/4d &values
0x402000 : 10 100 20 25
(gdb) x/4x &values
0x402000 : 0x0000000a 0x00000064 0x00000014 0x00000019
(gdb) x/4t &values
0x402000 : 00000000000000000000000000001010 00000000000000000000000001100100 00000000000000000000000000010100 00000000000000000000000000011001

$ ./i.a
$ echo $?
100



CF Carry flag A mathematical expression has created a carry or borrow
OF Overflow flag An integer value is either too large or too small
PF Parity flag The register contains corrupt data from a mathematical operation
SF Sign flag Indicates whether the result is negative or positive
ZF Zero flag The result of the mathematical operation is zero

Instruction Pair .......Description ..............EFLAGS Condition
CMOVA/CMOVNBE ......Above/not below or equal .....(CF or ZF) = 0
CMOVAE/CMOVNB ......Above or equal/not below .....CF=0
CMOVNC .............Not carry ....................CF=0
CMOVB/CMOVNAE ......Below/not above or equal .....CF=1
CMOVC ..............Carry ........................CF=1
CMOVBE/CMOVNA ......Below or equal/not above .....(CF or ZF) = 1
CMOVE/CMOVZ ........Equal/zero ...................ZF=1
CMOVNE/CMOVNZ ......Not equal/not zero ...........ZF=0
CMOVP/CMOVPE .......Parity/parity even ...........PF=1
CMOVNP/CMOVPO ......Not parity/parity odd ........PF=0
CMOVGE/CMOVNL ......Greater or equal/not less ....(SF xor OF)=0
CMOVL/CMOVNGE ......Less/not greater or equal ....(SF xor OF)=1
CMOVLE/CMOVNG ......Less or equal/not greater ....((SF xor OF) or ZF)=1
CMOVO ..............Overflow .....................OF=1
CMOVNO .............Not overflow .................OF=0
CMOVS ..............Sign (negative) ..............SF=1
CMOVNS .............Not sign (non-negative) ......SF=0


# cmv
.section .data
output:
.asciz “The largest value is %d\n”
va:
.int 105, 235, 61, 315, 134, 221, 53, 145, 117, 5
.section .text
.globl _start
_start:
nop
movl va, %ebx
movl $1, %edi
loop:
movl va(, %edi, 4), %eax
cmp %ebx, %eax
cmova %eax, %ebx
inc %edi
cmp $10, %edi
jne loop
pushl %ebx
pushl $output
call printf
addl $8, %esp
pushl $0
call exit

(gdb) s
14 movl va(, %edi, 4), %eax
(gdb) s
15 cmp %ebx, %eax
(gdb) print $eax
$1 = 235
(gdb) print $ebx
$2 = 105
(gdb) s
16 cmova %eax, %ebx
(gdb) s
17 inc %edi
(gdb) print $ebx
$3 = 235
$ ./cmv
The largest value is 315


exchange of values:
MOVW %AX , %CX # TMP , cx spare register
MOVW %BX , %AX
MOVW %CX , %AX


The BSWAP instruction reverses the order of the bytes in a register.



It is important to remember that the bits are not reversed; but rather, the individual bytes contained within the register are reversed. This produces a big-endian value from a little-endian value, and visa versa.

movl $0x12345678, %ebx #######
Current language: auto; currently asm
(gdb) step
_start () at swaptest.s:
bswap %ebx ######## (gdb) print/x $ebx
$1 = 0x12345678
(gdb) step
_start () at swaptest.s:7
7 movl $1, %eax ######## after this instruction the bytes result reversed
(gdb) print/x $ebx
$2 = 0x78563412 ############ 4 bytes reversed



XADD
The XADD instruction is used to exchange the values between two registers, or a memory location and a register, add the values, and then store them in the destination location (either a register or a memory location). The format of the XADD instruction is
xadd source, destination
where source must be a register, and destination can be either a register or a memory location, and contains the results of the addition. The registers can be 8-, 16-, or 32-bit register values.


CMPXCHG
The CMPXCHG instruction compares the destination operand with the value in the EAX, AX, or AL registers. If the values are equal, the value of the source operand value is loaded into the destination operand. If the values are not equal, the destination operand value is loaded into the EAX, AX, or AL registers. The CMPXCHG instruction is not available on processors earlier than the 80486. In the GNU assembler, the format of the CMPXCHG instruction is
cmpxchg source, destination
which is the reverse of the Intel documents. The destination operand can be an 8-, 16-, or 32-bit register, or a memory location. The source operand must be a register whose size matches the destination operand.

# prog
.section .data
data:
.int 10
.section .text
.globl _start
_start:
nop
movl $10, %eax
movl $5, %ebx
cmpxchg %ebx, data
movl $1, %eax
int $0x80
The memory location referenced by the data label is compared with the value in the EAX register using the CMPXCHG instruction. Because they are equal, the value in the source operand (EBX) is loaded in the data memory location, and the value in the EBX register remains the same. You can check this behavior using the debugger:
(gdb) run
9 movl $10, %eax
(gdb) step
10 movl $5, %ebx
(gdb) step
11 cmpxchg %ebx, data
(gdb) x/d &data
0x8049090 : 10
(gdb) s
12 movl $1, %eax
(gdb) print $eax $3 = 10

(gdb) print $ebx
$4 = 5 (gdb) x/d &data
0x8049090 : 5
(gdb)
Before the CMPXCHG instruction, the value of the data memory location is 10, which matches the value set in the EAX register. After the CMPXCHG instruction, the value in EBX (which is 5) is moved to the data memory location.
Because that value does not match the value in EAX, you will notice that the data value is not changed, but the EAX value now contains the value you set in the data label.

//8
.section .data
dat:
.byte 0x88, 0x77 , 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
.section .text
.globl _start
_start:
nop
movl $0x88776655 , %edx #32 bit
movl $0x44332211 , %eax
movl $0x22222222 , %ecx
movl $0x11111111 , %ebx
cmpxchg8b dat
movl $0 , %ebx
movl $1 , %eax
int $0x80

(gdb) x/2x &dat
0x402000 : 0x55667788 0x11223344


//88 .section .data
dat:
.byte 0x11, 0x22 , 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
.section .text
.globl _start
_start:
nop
movl $0x88776655 , %edx
movl $0x44332211 , %eax
movl $0x22222222 , %ecx
movl $0x11111111 , %ebx
cmpxchg8b dat
movl $0 , %ebx
movl $1 , %eax
int $0x80

(gdb) x/2x &dat
0x402000 : 0x11111111 0x22222222















movl $va, %edi

This instruction moves the memory address of the label VA to the EDI register.
The dollar sign ($) before the label name instructs the assembler to use the memory address, and not the data value located at the address.

next instruction:

movl %ebx, (%edi)

is the other half of the indirect addressing mode.
Without the parentheses around the EDI register, the instruction would just load the value in the EBX register to the EDI register. With the parentheses around the EDI register, the instruction instead moves the value in the EBX register to the memory location, the label VA, contained in the EDI register.

This is a very powerful tool. Similar to pointers in C and C++, it enables you to control memory address locations with a register. The real power is realized by incrementing the indirect addressing value contained in the register.

movl %edx, 4(%edi)

This instruction places the value contained in the EDX register in the memory location 4 bytes after the location pointed to by the EDI register. You can also go in the opposite direction:

movl %edx, -4(&edi)

This instruction places the value in the memory location 4 bytes before the location pointed to by the EDI register.






HOME PAGE