Chinaunix首页 | 论坛 | 博客
  • 博客访问: 984982
  • 博文数量: 633
  • 博客积分: 30780
  • 博客等级: 大将
  • 技术积分: 7532
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-12 21:07
文章分类

全部博文(633)

文章存档

2011年(10)

2010年(500)

2009年(47)

2008年(76)

我的朋友

分类:

2011-03-06 21:13:28

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) |
0

上一篇:(2) 内存操作

下一篇:(4)指令跳转

给主人留下些什么吧!~~