Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 操作系统 > Linux > at&t汇编说明
【标  题】:at&t汇编说明
【关键字】:at,amp
【来  源】:http://blog.chinaunix.net/article.php?articleId=45997&blogId=6728

at&t汇编说明

Your Ad Here at&t汇编说明 rainfall兄作品

itle: at&t汇编语法简单说明 这些是从网上的一些资料整理而得,不知道说清楚了没有,或是有什么错误,请指正。 1:寄存器引用 引用寄存器要在寄存器号前加%,如 mov % eax, % ebx 2: 操作数顺序 操作数排列是从源(左)到目的(右),如 mov % eax(源), % ebx(目的) 3: 常数/立即数的格式 使用立即数,要在数前面加 $, 如 mov , % ebx
符号常数直接引用 如 mov value , % ebx (value是一常数,已在前面定义)
引用符号地址在符号前加 $, 如 mov $value, % ebx (是将value的地址放到ebx中)

4:操作数的长度
操作数的长度用加在指令后的符号表示
b(byte), w(word), l(long) 如 movw %ax,%bx

5:寻址方式
内存寻址可以用
section:disp(base, index, scale) 表示,计算方法是
base + index*scale + disp, section在实模式下有用,保护模式下用线性地址,不用section。
例如:
call *SYMBOL_NAME(sys_call_table)(,% eax,4)
这是entry.S中的一句,对应应该是
% eax*4 + sys_call_table, 在sys_call_table中找到相应系统调用的地址。


二 基本的行内汇编

基本的行内汇编很简单,一般是按照下面的格式
asm("statements");
例如:asm("nop"); asm("cli");
asm 和 __asm__是完全一样的.
如果有多行汇编,则每一行都要加上 "\n\t"
例如:
asm( "pushl % eax\n\t"
"movl ,% eax\n\t"
"popl % eax");
实际上gcc在处理汇编时,是要把asm(...)的内容"打印"到汇编
文件中,所以格式控制字符是必要的.

再例如:
asm("movl % eax,% ebx");
asm("xorl % ebx,% edx");
asm("movl ,_booga);

在上面的例子中,由于我们在行内汇编中改变了edx和ebx的值,但是
由于gcc的特殊的处理方法,即先形成汇编文件,再交给GAS去汇编,
所以GAS并不知道我们已经改变了edx和ebx的值,如果程序的上下文
需要edx或ebx作暂存,这样就会引起严重的后果.对于变量_booga也
存在一样的问题.为了解决这个问题,就要用到扩展的行内汇编语法.

三 扩展的行内汇编
基本的格式是:
asm( statements : outputs : inputs : registers-modified);
statements是一些汇编语句,outputs是输出寄存器,inputs是输入寄存器,registers-modified
是在这个过程中改变的寄存器。
例如:

int i=0, j=1, k=0;
__asm__ __volatile__("
pushl %% eax\n
movl %1, %% eax\n
addl %2, %% eax\n
movl %% eax, %0\n
: "=g" (k)
: "g" (i), "g" (j)
); // k = i + j

在上面的这段代码中,输入寄存器用了"g"限定符,它的意思是将输入变量放入
eax,ebx,ecx,edx或内存变量其中之一,类似的限定还有:
"a" eax
"b" ebx
"c" ecx
"d" edx
"S" esi
"D" edi
"q" 从eax,ebx,ecx,edx分配寄存器
"r" 从eax,ebx,ecx,edx,esi,edi分配寄存器
"g" eax,ebx,ecx,edx或内存变量
"A" 把eax和edx合成一个64位的寄存器(use long longs)
"I" I是常数值,例如"1",它是把输出寄存器和输入寄存器由左到右,由上到下顺序往下数对应的寄存器
在上面这段代码中,%0对应k存放的寄存器,,%1对应i存放的寄存器,%2对应j存放的寄存器.
"i" 立即数
"m" 内存变量
输出寄存器要在前面加"=",指示输出的位置。
上面的代码展开大概是:
mov i, % eax
mov j, % ebx
pushl %% eax
movl % eax, %% eax
movl % ebx, %% eax
movl %% eax, % ecx
popl %% eax

又如:
do { \
int __d0, __d1; \
__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
"movw %4,%%dx\n\t" \
"movl %% eax,%0\n\t" \
"movl %% edx,%1" \
:"=m" (*((long *) (gate_addr))), \
"=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
"3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
} while (0)中
%3 对应edx, %2对应eax, %1是(*(1+(long *) (gate_addr))). 这段代码是将中断处理函数的地址填到
ldt(中断向量表)中。

象专业人员那样截断字符串:【上一篇】
近期Debian下的技巧总结:【下一篇】
【相关文章】
  • iptables+NAT+端口映射
  • Segmentation fault code
  • QT&GTK
  • RedHat 9.0及8.0美化
  • 在redhat中建立交换分区
  • apache用户验证与虚拟主机包括整合tomcat的虚拟主机
  • oracle9.2.0 for RedHat8.0安装手册
  • Linux和DOS的FORMAT命令区别
  • What is netfilter/iptables?
  • The Double NAT MINI-HOWTO
  • 【随机文章】
  • Matlab7无法启动的一个解决方法
  • Solaris FTP issue
  • solaris8学习资料 - 第七课
  • 用shell读文件
  • 宽带接入技术的发展与应用
  • 资源管理器也玩多窗口
  • 红帽企业 Linux AS 4 中文解决
  • 证券交易所组网方案实例
  • 教你如何学习GRUB
  • 单独播放就始终停在一个?上而且?速
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.