定義數據
數據段
.data 和 .rodata
數據類型:
* ascii 字符串
* asciz 0結束的字符串
* byte 字節值
* double 雙精度浮點數
* float 單精度浮點數
* int 32位整數
* long 32位整數
* octa 16位整數
* quad 8位整數
* short 16位整數
* single 單精度浮點數
示例:
.section .data
msg:
.ascii "this is a test message"
factors:
.double 37.45, 45.33, 12.30
height:
.int 54
length:
.int 62,35,47
定義靜態符號
示例:
.equ factor, 3
.equ LINUX_SYS_CALL, 0x80
movl $LINUX_SYS_CALL, %eax
bss 段
命令:
* comm 聲明一段未初始化的內存區域
* .lcomm 生命一段本地的未初始化的內存區域(不能被其他文件訪問)
格式:
.comm sysbol, length
示例:
.section .bss
.lcomm buffer, 10000
移動數據
移動命令
- 格式:
movx source, destination
x標識操作的位
l 32位
w 16位
b 8位 - 規則:
- 立即數到一般寄存器
- 立即數到內存單元
- 一般寄存器到另外一個一般寄存器
- 一般寄存器到段寄存器
- 段寄存器到一般寄存器
- 一般寄存器到段寄存器
- 控制寄存器到一般寄存器
- 一般寄存器到調試寄存器
- 調試寄存器到一般寄存器
- 內存單元到一般寄存器
- 內存單元到段寄存器
- 一般寄存器到內存單元
- 段寄存器到內存單元
- 示例:
#movtest2.s - An example of moving register data to memory
.section .data
value:
.int 1
.section .text
.globl _start
_start:
nop
movl $100, %eax
movl %eax, value
movl $1, %eax
movl $0, %ebx
int $0x80
- 調試
- as -o movtest2.o -gstabs movtest2.s
- ld -o movtest2 movtest.o
- gdb -q movtest2
- break *_start+1
- run
- x/d &value
- s
- s
- x/d &value
使用索引訪問內存
- 格式:
base_address(offset_address, index, size) - 示例:
# movtest3.s - Another example of using indexd memory locations
.section .data
output:
.asciz "The value is %d\n"
values:
.int 10, 15, 20,25,30,35,40,45,50,55,60
.section .text
.globl _start
_start:
nop
movl $0, %edi
loop:
movl values(, %edi, 4), %eax
pushl %eax
pushl $output
call printf
addl $8, %esp
inc %edi
cmpl $11, %edi
jne loop
movl $0, %ebx
movl $1, %eax
int $0x80
- 執行
- as -o movtest3.o movtest3.s
- ld -dynamic-linker /lib/ld-linux.so.2 -lc -o movtest3 movtest3.o
使用寄存器間接地址訪問
- 格式:
- mov $values, %edi 將values的地址存入edi
- mov %ebx, (%edi) 將ebx的值存入edi所存的內存中
- 示例:
#movtest4.s - An example of indirect addressing
.section .data
values:
.int 10, 15, 20, 25, 30, 35, 40, 45, 55, 60
.section .text
.globl _start
_start:
nop
movl values, %eax
movl $values, %edi
movl $100, 4(%edi)
movl $1, %edi
movl values(, %edi, 4), %ebx
movl $1, %eax
int $0x80
條件mov指令
- 格式:
cmovx source, destination
x代表跳轉條件的字符
* CF 進位標識
* OF 溢出標識
* PF 奇偶標識
* SF 正負標識
* ZF 零標識
無符號數跳轉
指令 | 描述 | 符號位 |
---|---|---|
CMOVA/CMOVNBE | 大於或者不小於等於 | (CF or ZF) = 0 |
CMOVAE/CMOVNB | 大於等於或者不小於 | CF=0 |
CMOVNC | 沒有進位 | CF=0 |
CMOVVB/CMOVNAE | 小於 | CF=1 |
CMOVC | 有進位 | CF=1 |
CMOVBE/CMOVNA | 不大於 | (CF or ZF) = 1 |
CMOVE/CMOVZ | 等於 | ZF=1 |
CMOVNE/CMOVNZ | 不等於 | ZF=0 |
CMOVP/CMOVPE | 字節1爲偶數個 | PF=1 |
CMOVNP/CMOVPO | 字節1爲奇數 | PF=0 |
有符號數跳轉
指令 | 描述 | 符號位 |
---|---|---|
CMOVGE/CMOVNL | 大於等於 | (SF xor OF)=0 |
CMOVL/CMOVNGE | 小於 | (SF xor OF) = 1 |
CMOVLE/VMOVNG | 小於等於 | ((SF xor OF) or ZF) = 1 |
CMOVO | 溢出 | OF=1 |
CMOVNO | 沒有溢出 | OF=0 |
CMOVS | 正數 | SF=1 |
CMOVNS | 非正 | SF=0 |
使用CMOV指令
#cmovtest.s - An example of the CMOV instructions
.section .data
output:
.asciz "The largest value is %d\n"
valuse:
.int 105, 235, 61, 315, 134, 221, 53, 145, 117, 5
.section .text
.globl _start
_start:
nop
movl values, %ebx
movl $1, %edi
loop:
movl values(, %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
交換數據
數據交換指令
* XCHG 交換兩個寄存器或者一個寄存器一個內存單元
* BSWAP 反轉32爲寄存器的字節順序
* XADD 交換兩個數並將和存儲在目的操作數
* CMPXCHG 比較交換
* CMPXCHG8B 比較交換兩個64位數
使用數據交換指令
# bubble.s - An example of the XCHG instruction
.section .data
values:
.int 105, 235, 61, 315, 134, 221, 53, 145, 117, 5
.section .text
.globl _start
_start:
movl $values, %esi
movl $9, %ecx
movl $9, %ebx
loop:
movl (%esi), %eax
cmp %eax, 4(%esi)
jge skip
xchg %eax, 4(%esi)
movl %eax, (%esi)
skip:
add $4, %esi
dec %ebx
jnz loop
dec %ecx
jz end
movl $values, %esi
mov %ecx, %ebx
jmp loop
end:
movl $1, %eax
movl $0, %ebx
int $0x80
棧
棧是如何工作的
出棧和入棧
*語法:
pushx source
pop destination
- 將所有的寄存器入棧出棧
- PUSHA/POPA 將所有的16位一般寄存器入棧/出棧
- PUSHAD/POPAD 將所有的32位寄存器入棧/出棧
- PUSHF/POPF 將16位的符號寄存器入棧/出棧
- PUSHFD/POPFD 將32位的符號寄存器入棧/出棧