在64位下编译32位汇编
as --32 exit.s -o exit.o
ld exit.o -o exit -m elf_i386
在64位下编译64位汇编
as exit.s -o exit.o
ld exit.o -o exit
.section .data
.section .text
.globl _start
_start:movl $1,%eaxmovl $2,%ebxint $0x80
求最大值
movq | 64位操作数 |
---|---|
movl | 32位操作数 |
movw | 16位操作数 |
movb | 8位操作数 |
其它指令也遵循这一规则
比较指令的使用方式
.section .data
data_items:
.long 3,67,234,98,1,3,234,93,234,93,0
.section .text
.globl _start
_start:movl $0,%edimovl data_items(,%edi,4),%eaxmovl %eax,%ebx
start_loop:cmpl $0,%eaxje loop_exitincl %edimovl data_items(,%edi,4), %eaxcmpl %ebx,%eaxjle start_loopmovl %eax,%ebxjmp start_loop
loop_exit:movl $1,%eaxint $0x80
“hello world\0”
movl variable(base_offset,index,step_length)
variable
和step_lenth
必须为常数,缺省为0
base_offset
和index
必须为寄存器,缺省为0
例 movl array(,%edi,4)
,addr=array+off+edi∗4addr=array+off+edi*4addr=array+off+edi∗4
缺省用法:
movl 0x3ffff,%eax
直接读内存地址不常用。movl (%eax),%ebx
movl 2(%eax),%ebx
不使用c的变量直接用asm包起来,单行
#include
int func(){asm("movl $23,%eax");
}
int main(){printf("%d ",func());
}
volatile,防止编译器优化,重排指令
#include
int func(){asm volatile ("movl $23,%eax");
}
int main(){printf("%d ",func());
}
由于是嵌入式汇编,那么我们自然希望能在汇编中使用c语言的全局变量,静态变量和局部变量、参数等。
asm asm-qualifiers (AssemblerInstructions)
int main(){printf("a"\"b");printf("a\
b");
}
优点:能够使用C语言的变量和跳转标签,更加智能化,且编译器能感知到内部的代码。
缺点:放弃了完全控制生成的机器码的样式,由编译器按需增加一些汇编代码。
asm asm-qualifiers ( AssemblerTemplate: OutputOperands[ : InputOperands[ : Clobbers ] ])
asm asm-qualifiers ( AssemblerTemplate: OutputOperands: InputOperands: Clobbers: GotoLabels)
代码模板,像汇编指令,但又有所扩展,就好比c++模板函数和普通函数的区别一样。
输出操作数,即汇编代码写出的变量的值,这些变量即是输出操作数
输入操作数,即汇编代码读入变量的值,这些变量即是输入操作数
被汇编代码改变的寄存器和变量
用到的C语言标签
实例 :输入操作数,即我们的指令用到的寄存器的值需要从变量里获得
反汇编发现,gcc喜欢把寄存器参数给压到栈上,暂时跳过。
#include
int add(int a,int b){asm ("addl %1,%0"::"a"(b),"r"(a));
}
int add2(int a,int b){return a+b;
}
int main(){printf("%d ",add(3,44));printf("%d ",add2(3,44));
}
#include
int add(int a,int b){asm ("addl %1,%0":"+a"(b),"+r"(a));
}
int add2(int a,int b){return a+b;
}
int main(){printf("%d ",add(3,44));printf("%d ",add2(3,44));
}
获取最低非0位,利用bsfl
指令
#include
int main(){unsigned int num=1;int width;for(int i=0;i<32;i++){__asm__("bsfl %1,%0":"=r"(width):"r"(num));printf("%d ",width);num<<=1;}
}
%0 和%1会使用同一个寄存器
#include
int main(){int a=1,b=2;asm volatile("movl $10,%0\n\t""movl $20,%1":"=r"(a):"r"(b));printf("a=%d,b=%d",a,b);
}
#include
int main(){int a=1,b=2;asm volatile("movl $10,%0\n\t""movl $20,%1":"=&r"(a):"r"(b));printf("a=%d,b=%d",a,b);
}
下一篇:腿姐三十天带背