1. 条件传送指令分两部分,一是有符号数的条件传送,二是无符号数的条件传送
cmova是无符号数的条件传送指令,表示“大于/不小于或者等于”
举一个实例:
[root@localhost assembly_study]#
[root@localhost assembly_study]# cat cmovtest.s
.section .data
values:
.int 105,235,61,315,134,221,53,145,117,5
output:
.asciz "The largest value is %d\n"
.section .text
.global _start
_start:
nop;
movl $1, %edi #put index into %edi
movl values, %eax #put the biggest value into %eax
loop:
cmp %eax, values(,%edi,4)
cmova values(,%edi,4), %eax
inc %edi
cmp $10, %edi
jnz loop
pushl %eax
pushl $output
call printf
addl $8, %esp
pushl $0
call exit
[root@localhost assembly_study]#
|
因为用到了C库函数(printf和exit),所以链接的时候要加入对应的选项:
as -gstabs -o cmovtest.o cmovtest.s
ld -o cmovtest -dynamic-linker /lib/ld-linux.so.2 -lc cmovtest.o
[root@localhost assembly_study]# ./cmovtest The largest value is 315
|
Good!
2. 数据交换指令
XCHG 在两个寄存器之间或者寄存器与内存之间交换数据
BSWAP 反转一个32位寄存器中的
字节顺序(注意,不是bit顺序)
XADD 交换两个值并且把总和存储在目标操作数中
CMPXCHG 把一个值和一个外部值进行比较,并且交换它和另一个值(有点晕了)
CMPXCHG8B 比较两个64位值并且交换它们
注意:XCHG这条指令,当一个操作数是内存位置时,处理器的LOCK信号被自动标明,防止在交换过程中任何其他处理器访问这个内存位置。使用XCHG对内存位置进行操作时要小心。LOCK处理是非常耗费时间的,并且可能对程序性能有不良影响。BSWAP是bit endian和little endian转换的利器
下面是一个简单的例子,可以通过gdb调试:
[root@localhost assembly_study]# as -gstabs -o swaptest swaptest.s [root@localhost assembly_study]# ld -o swaptest swaptest.s [root@localhost assembly_study]# as -gstabs -o swaptest.o swaptest.s [root@localhost assembly_study]# ld -o swaptest swaptest.o [root@localhost assembly_study]# ./swaptest [root@localhost assembly_study]# gdb swaptest GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"... (gdb) list 1 .section .text 2 .global _start 3 _start: 4 nop 5 movl $0x12345678, %ebx 6 bswap %ebx 7 movl $1, %eax 8 int $0x80 (gdb) list Line number 9 out of range; swaptest.s has 8 lines. (gdb) break *start+1 No symbol "start" in current context. (gdb) break *_start+1 Breakpoint 1 at 0x8048075: file swaptest.s, line 5. (gdb) ru Starting program: /home/assembly_study/swaptest
Breakpoint 1, Current language: auto; currently asm (gdb) print %ebx A parse error in expression, near `%ebx'. (gdb) print $ebx $1 = 0 (gdb) s 6 bswap %ebx (gdb) print $ebx $2 = 305419896 (gdb) print/x $ebx $3 = 0x12345678 (gdb) s 7 movl $1, %eax (gdb) print/x $ebx $4 = 0x78563412 (gdb) cont Continuing.
Program exited with code 022. (gdb)
|
我们再来看下CMPXCHG指令:
CMPXCHG指令比较目标操作数和EAX,AX或者AL寄存器中的值。如果两个值相等,就把原操作数的值加载到目标操作数中。如果两个值不等,就把目标操作数加载到EAX,AX或者AL寄存器中。
举个例:
[root@localhost assembly_study]# cat cmpxchtest.s
.section .data
data:
.int 10
.section .text
.global _start
_start:
nop
movl $10, %eax
movl $5 , %ebx
cmpxchg %ebx, data
movl $1, %eax
int $0x80
[root@localhost assembly_study]#
|
看看单步的结果:
[root@localhost assembly_study]# gdb cmpxchtest
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) break *_start+1
Breakpoint 1 at 0x8048075: file cmpxchtest.s, line 9.
(gdb) run
Starting program: /home/assembly_study/cmpxchtest
Breakpoint 1, <function called from gdb>
Current language: auto; currently asm
(gdb) print/x data
$1 = 0xa
(gdb) s
10 movl $5 , %ebx
(gdb) s
11 cmpxchg %ebx, data
(gdb) print/x data
$2 = 0xa
(gdb) s
12 movl $1, %eax
(gdb) print/x data
$3 = 0x5
(gdb) cont
Continuing.
Program exited with code 05.
(gdb) quit
|
3. 堆栈操作
PUSHA/POPA 压入或者弹出所有16位通用寄存器
PUSHAD/POPAD 压入或者弹出所有32位通用寄存器
PUSHF/POPF 压入或者弹出EFLAGS寄存器的低16位
PUSHFD/POPFD 压入或者弹出EFLAGS寄存器的全部32位
注意,PUSHA/PUSHAD压入寄存器的顺序是:
DI/EDI, SI/ESI, BP/EBP, BX/EBX, DX/EDX, CX/EDX, AX/EAX
同理,POPA/POPAD弹出到寄存器的
顺序与上面的刚好相反
疑问:在vxworks的代码里,看到的是pushal,popal,pushfl,popfl
这里的l与前面的d是不是一回事呢?
阅读(2487) | 评论(0) | 转发(0) |