首先你需要设置一下emulator工具的目录之类的,这个不细说了,
要在.bashrc中新增环境变量,如下
android_PRODUCT_OUT=~/android/out/target/proct/generic
ANDROID_PRODUCT_OUT_BIN=~/android/out/host/linux-x86/bin
这里是设置你的输出文件的位置和bin工具目录,不用多解释吧?
然后在命令行输入:
export PATH=${PATH}:${ANDROID_PRODUCT_OUT_BIN}:${ANDROID_PRODUCT_OUT};
上面是导入了相关的配置,然后使之生效。
source ~/.bashrc
接着切换到输出的system文件夹
cd ~/android/out/target/proct/generic
然后来创建模拟器
emulator -system system.img -data userdata.img -ramdisk ramdisk.img
如果你运气够好的话,也许现在已经在运行了,不过我运气明显不够好。
提示一:
emulator: ERROR: You did not specify a virtual device name, and the system
directory could not be found.
If you are an Android SDK user, please use ‘@<name>’ or ‘-avd <name>’
to start a given virtual device (see -help-avd for details).
Otherwise, follow the instructions in -help-disk-images to start the emulator
既然人家提示了,那就按照步骤走吧,输入命令:
emulator -help-avd
接着提示如下:
use ‘-avd <name>’ to start the emulator program with a given Android
Virtual Device (a.k.a. AVD), where <name> must correspond to the name
of one of the existing AVDs available on your host machine.
See -help-virtual-device to learn how to create/list/manage AVDs.
As a special convenience, using ‘@<name>’ is equivalent to using
‘-avd <name>’.
跟着提示继续走,输入命令:
emulator -help-virtual-device
又是提示了:
An Android Virtual Device (AVD) models a single virtual
device running the Android platform that has, at least, its own
kernel, system image and data partition.
Only one emulator process can run a given AVD at a time, but
you can create several AVDs and run them concurrently.
You can invoke a given AVD at startup using either ‘-avd <name>’
or ‘@<name>’, both forms being equivalent. For example, to launch
the AVD named ‘foo’, type:
emulator @foo
The ‘android’ helper tool can be used to manage virtual devices.
For example:
android create avd -n <name> -t 1 # creates a new virtual device.
android list avd # list all virtual devices available.
Try ‘android –help’ for more commands.
Each AVD really corresponds to a content directory which stores
persistent and writable disk images as well as configuration files.
Each AVD must be created against an existing SDK platform or add-on.
For more information on this topic, see -help-sdk-images.
B. 手机CPU可以用X86指令集吗
所谓X86指令集是复杂指令集指令系统非常丰富,命令通常也很复杂,这样对操作发出的指令也有针对性,执行效率更高;手机CPU采用的ARM构架的CPU使用的是精简指令集它的特点是针对常用的命令进行优化,让他赋予更简洁的执行环境。
二者不能互相兼容,手机CPU如果运行X86程序需要重新编译(类似模拟器),会加大CPU负担,目前的手机CPU性能不能满足要求。
C. x86汇编指令与二进制关系问题
你的问题我很难明白,如果你所谓MIX值的是LINUX下的汇编,那么请参考:
http://cache..com/c?m=&p=8b2a941e838b13c308e2952813&user=
下面谈点无关的内容,能更深刻地理解计算机。
不管哪种指令都是一样的。核心即“操作码+操作数”。至于用什么二进制序组合序列表示哪种命令,这是由硬件设计决定的。比如这种机器(假设为X86)0010表示“X指令”,那种机器0010(假设为MMIX)表示“Y指令”也是可以的;这种机器有“Z指令”,那种机器也可以没有“Z指令”。至于汇编语句的不同,完全由编译器决定。比如我自己写一个支持X86的汇编编译器,完全可以让“老板是王八蛋”表示“X指令”,因为最终都会被汇编器翻译成0010。同样,你可以写一个支持MMIX的汇编编译器,让“老板是再生父母”表示“Y指令”,汇编器会为你翻译成0010。当然,还有很多是由硬件体系结构决定而非编译器能改变的,比如模式、寻址方式什么的。
什么是MMIX,参考:
http://cache..com/c?m=&p=9c759a44d3981eee09b6c7710d5e&user=
D. x86汇编指令的特点是什么
简单点说,所有的对操作数进行算术和逻辑运算的指令,都会根据运算结果修改ZF标志。
第一点:
大多数情况下,运算结果对ZF的修改,由结果是否为0决定。
若运算结果为0,则ZF=1;
若运算结果非0,则ZF=0.
举些例子吧:
加法指令,比如ADD, ADC, INC,等
减法指令,比如SUB, SBB, CMP, DEC, NEG, 等
逻辑运算指令,比如AND, TEST, OR, XOR, NOT等
逻辑移位指令,比如SHL, SHR, SAL, SAR, RCL, RCR等(ROL,ROR不会改变ZF,原因可自己分析)
调整指令,比如AAA, AAS,等
串指令中含有算术运算的那些,比如CMPS, SCAS等
控制转移指令中含有算术运算的,比如LOOP
第二点:
但是,也有一些指令,会改变ZF标志,但其结果具有不确定性,没有运算结果是否为0的意义。
比如乘法指令 MUL和IMUL, 除法指令DIV和IDIV等
改变标志寄存器内容的SAHF指令,堆栈操作中的POPF指令,也不具有运算结果的意义。
E. 如何编译android x86模拟器
首先你需要设置一下emulator工具的目录之类的
要在.bashrc中新增环境变量,如下
ANDROID_PRODUCT_OUT=~/android/out/target/proct/generic
ANDROID_PRODUCT_OUT_bin=~/android/out/host/linux-x86/bin
这里是设置你的输出文件的位置和bin工具目录
然后在命令行输入:
export path=${path}:${ANDROID_PRODUCT_OUT_bin}:${ANDROID_PRODUCT_OUT};
上面是导入了相关的配置,然后使之生效。
source ~/.bashrc
接着切换到输出的system文件夹
cd ~/android/out/target/proct/generic
然后来创建模拟器
emulator -system system.img -data userdata.img -ramdisk ramdisk.img
如果你运气够好的话,也许现在已经在运行了,不过我运气明显不够好。
提示一:
emulator: ERROR: You did not specify a virtual device name, and the system
directory could not be found.
If you are an Android sdk user, please use ‘@<name>’ or ‘-avd <name>’
to start a given virtual device (see -help-avd for details).
Otherwise, follow the instructions in -help-disk-images to start the emulator
既然人家提示了,那就按照步骤走吧,输入命令:
emulator -help-avd
接着提示如下:
use ‘-avd <name>’ to start the emulator program with a given Android
Virtual Device (a.k.a. AVD), where <name> must correspond to the name
of one of the existing AVDs available on your host machine.
See -help-virtual-device to learn how to create/list/manage AVDs.
As a special convenience, using ‘@<name>’ is equivalent to using
‘-avd <name>’.
跟着提示继续走,输入命令:
emulator -help-virtual-device
又是提示了:
An Android Virtual Device (AVD) models a single virtual
device running the Android platform that has, at least, its own
kernel, system image and data partition.
Only one emulator process can run a given AVD at a time, but
you can create several AVDs and run them concurrently.
You can invoke a given AVD at startup using either ‘-avd <name>’
or ‘@<name>’, both forms being equivalent. For example, to launch
the AVD named ‘foo’, type:
emulator @foo
The ‘android’ helper tool can be used to manage virtual devices.
For example:
android create avd -n <name> -t 1 # creates a new virtual device.
android list avd # list all virtual devices available.
Try ‘android –help’ for more commands.
Each AVD really corresponds to a content directory which stores
persistent and writable disk images as well as configuration files.
Each AVD must be created against an existing sdk platform or add-on.
For more information on this topic, see -help-sdk-images.
延伸1):
Android x86模拟器Intel Atom x86 System Image配置与使用方法
大家现在开发使用的Android 模拟器模拟的是 arm 的体系结构(arm-eabi),因此模拟器并不是运行在x86上而是模拟的arm,所以我们调试程序的时候经常感觉到非常慢,大部分开发者应该都深有体会。
针对这种情况,前段时间intel推出了支持x86的Android模拟器,这将大大提高启动速度和程序的运行速度,这将允许Android模拟器能够以原始速度(真机运行速度)运行在使用intel x86处理器的电脑中,各位开发者有福了,下面将为大家展示使用方法。
一、首先下载intel提供的 intel® Hardware Accelerated Execution Manager 1.0.1(R2)
requirement:
1. requires the Android* SDK to be installed (version 17 or higher). SDK17或者以上
2.intel® processor with support for VT-x, EM64T, and Execute Disable (XD) bit functionality intel的cpu:并支持VT-X(虚拟化技术)、可扩展64位、Execute Disable bit。(均需要保证在bios中开启Enable)
3. At least 1 gb of available ram 1G以上内存,否则安装不了
满足硬件和软件要求之后,就可以开始安装了,一直下一步至安装成功。途中有个地方选择分配给HAXM内存大小,一般默认就好,分太多会拖慢整机速度。
安装成功后命令行输入sc query intelhaxm,查看运行状态: state is: “4 RUNNING” ,即代表安装成功。需要更改分配内存,重新运行一下安装程序选择change即可修改。
还可以使用以下指令手动开启和关闭:
Stop: sc stop intelhaxm
Start:
sc start intelhaxm
满足软硬件条件,若提示如下Error:but intel Execute Disable bit (XD) is not turned on......
(需要开启系统数据执行保护功能dep,下午纠结了好久才查到。官网原文:Windows* hosts may need to enable dep (Data Execution Prevention) in addition to intel XD)
命令行使用指令:bcdedit.exe /set nx optin 打开即可,需要重启电脑
二、下载Intel Atom x86 System Image
1. 从SDK Manager下载:打开SDK Manager,展开至Android2.3.3(API10)(注意:目前只有2.3.3和4.0.3(Ice Cream Sandwich)有x86的Image),需要和2.3.3的SDK Platform配合使用。
2.使用avd Manager创建一个新的avd: Hardware Property里面选择gpu emulation yes 还有 Keyboard support yes
3.开始使用飞速的模拟器吧,各种爽歪歪
好的工具可以更有效率的开发APP,让我们从此告别那龟速的模拟器吧
F. X86指令集的内容有哪些
x86汇编指令集
数据传输指令 它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
MOVSX reg16,r/m8 ; o16 0F BE /r [386]
MOVSX reg32,r/m8 ; o32 0F BE /r [386]
MOVSX reg32,r/m16 ; o32 0F BF /r [386]
MOVZX reg16,r/m8 ; o16 0F B6 /r [386]
MOVZX reg32,r/m8 ; o32 0F B6 /r [386]
MOVZX reg32,r/m16 ; o32 0F B7 /r [386]
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )
XADD 先交换再累加.( 结果在第一个操作数里 )
XLAT 字节查表转换.
—— BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即
0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )
输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,
其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.
例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.
例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.
例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.
例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.
例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.
例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
二、算术运算指令
———————————————————————————————————————
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEC 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.
IMUL 整数乘法.
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.
IDIV 整数除法.
以上两条,结果回送:
商回送AL,余数回送AH, (字节运算);
或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
三、逻辑运算指令
———————————————————————————————————————
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL
四、串指令
———————————————————————————————————————
DS:SI 源串段寄存器 :源串变址.
ES:DI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.
( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.
把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.
把源串中的元素(字或字节)逐一装入AL或AX中.
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.
是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
五、程序转移指令
———————————————————————————————————————
1>无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF过程返回.
2>条件转移指令 (短转移,-128到+127的距离内)
( 当且仅当(SF XOR OF)=1时,OP1 JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3>循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4>中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5>处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK 封锁总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
六、伪指令
———————————————————————————————————————
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
七、寄存器
1. Register usage in 32 bit Windows
Function parameters are passed on the stack according to the calling conventions listed on
page 13. Parameters of 32 bits size or less use one DWORD of stack space. Parameters
bigger than 32 bits are stored in little-endian form, i.e. with the least significant DWORD at the
lowest address, and DWORD aligned.
Function return values are passed in registers in most cases. 8-bit integers are returned in
AL, 16-bit integers in AX, 32-bit integers, pointers, and Booleans in EAX, 64-bit integers in
EDX:EAX, and floating-point values in ST(0). Structures and class objects not exceeding
64 bits size are returned in the same way as integers, even if the structure contains floating
point values. Structures and class objects bigger than 64 bits are returned through a pointer
passed to the function as the first parameter and returned in EAX. Compilers that don\'t
support 64-bit integers may return structures bigger than 32 bits through a pointer. The
Borland compiler also returns structures through a pointer if the size is not a power of 2.
Registers EAX, ECX and EDX may be changed by a procere. All other general-purpose
registers (EBX, ESI, EDI, EBP) must be saved and restored if they are used. The value of
ESP must be divisible by 4 at all times, so don\'t push 16-bit data on the stack. Segment
registers cannot be changed, not even temporarily. CS, DS, ES, and SS all point to the flat
segment group. FS is used for a thread environment block. GS is unused, but reserved.
Flags may be changed by a procere with the following restrictions: The direction flag is 0
by default. The direction flag may be set temporarily, but must be cleared before any call or
return. The interrupt flag cannot be cleared. The floating-point register stack is empty at the
entry of a procere and must be empty at return, except for ST(0) if it is used for return
value. MMX registers may be changed by the procere and if so cleared by EMMS before
returning and before calling any other procere that may use floating-point registers. All
XMM registers can be modified by proceres. Rules for passing parameters and return
values in XMM registers are described in Intel\'s application note AP 589 "Software
Conventions for Streaming SIMD Extensions". A procere can rely on EBX, ESI, EDI, EBP
and all segment registers being unchanged across a call to another procere.
2. Register usage in Linux
The rules for register usage in Linux appear to be almost the same as for 32-bit windows.
Registers EAX, ECX, and EDX may be changed by a procere. All other general-purpose
registers must be saved. There appears to be no rule for the direction flag. Function return
values are transferred in the same way as under Windows. Calling conventions are the
same, except for the fact that no underscore is prefixed to public names. I have no
information about the use of FS and GS in Linux. It is not difficult to make an assembly
function that works under both Windows and Linux, if only you take these minor differences
into account.
八、位操作指令,处理器控制指令
1.位操作指令,8086新增的一组指令,包括位测试,位扫描。BT,BTC,BTR,BTS,BSF,BSR
1.1 BT(Bit Test),位测试指令,指令格式:
BT OPRD1,OPRD2,规则:操作作OPRD1可以是16位或32位的通用寄存器或者存储单元。操作数OPRD2必须是8位立即数或者是与OPRD1操作数长度相等的通用寄存器。如果用OPRD2除以OPRD1,假设商存放在Divd中,余数存放在Mod中,那么对OPRD1操作数要进行测试的位号就是Mod,它的主要功能就是把要测试位的值送往CF,看几个简单的例子:
1.2 BTC(Bit Test And Complement),测试并取反用法和规则与BT是一样,但在功能有些不同,它不但将要测试位的值送往CF,并且还将该位取反。
1.3 BTR(Bit Test And Reset),测试并复位,用法和规则与BT是一样,但在功能有些不同,它不但将要测试位的值送往CF,并且还将该位复位(即清0)。
1.4 BTS(Bit Test And Set),测试并置位,用法和规则与BT是一样,但在功能有些不同,它不但将要测试位的值送往CF,并且还将该位置位(即置1)。
1.5 BSF(Bit Scan Forward),顺向位扫描,指令格式:BSF OPRD1,OPRD2,功能:将从右向左(从最低位到最高位)对OPRD2操作数进行扫描,并将第一个为1的位号送给操作数OPRD1。操作数OPRD1,OPRD2可以是16位或32位通用寄存器或者存储单元,但OPRD1和OPRD2操作数的长度必须相等。
1.6 BSR(Bit Scan Reverse),逆向位扫描,指令格式:BSR OPRD1,OPRD2,功能:将从左向右(从最高位到最低位)对OPRD2操作数进行扫描,并将第一个为1的位号送给操作数OPRD1。操作数OPRD1,OPRD2可以是16位或32位通用寄存器或存储单元,但OPRD1和OPRD2操作数的长度必须相等。
1.7 举个简单的例子来说明这6条指令:
AA DW 1234H,5678H
BB DW 9999H,7777H
MOV EAX,12345678H
MOV BX,9999H
BT EAX,8;CF=0,EAX保持不变
BTC EAX,8;CF=0,EAX=12345778H
BTR EAX,8;CF=0,EAX=12345678H
BTS EAX,8;CF=0,EAX=12345778H
BSF AX,BX;AX=0
BSR AX,BX;AX=15
BT WORD PTR [AA],4;CF=1,[AA]的内容不变
BTC WORD PTR [AA],4;CF=1,[AA]=1223H
BTR WORD PTR [AA],4;CF=1,[AA]=1223H
BTS WORD PTR [AA],4;CF=1,[AA]=1234H
BSF WORD PTR [AA],BX;[AA]=0;
BSR WORD PTR [AA],BX;[AA]=15(十进制)
BT DWORD PTR [BB],12;CF=1,[BB]的内容保持不变
BTC DWORD PTR [BB],12;CF=1,[BB]=76779999H
BTR DWORD PTR [BB],12;CF=1,[BB]=76779999H
BTS DWORD PTR [BB],12;CF=1,[BB]=77779999H
BSF DWORD PTR [BB],12;[BB]=0
BSR DWORD PTR [BB],12;[BB]=31(十进制)
2.处理器控制指令
处理器控制指令主要是用来设置/清除标志,空操作以及与外部事件同步等。
2.1 CLC,将CF标志位清0。
2.2 STC,将CF标志位置1。
2.3 CLI,关中断。
2.4 STI,开中断。
2.5 CLD,清DF=0。
2.6 STD,置DF=1。
2.7 NOP,空操作,填补程序中的空白区,空操作本身不执行任何操作,主要是为了保持程序的连续性。
2.8 WAIT,等待BUSY引脚为高。
2.9 LOCK,封锁前缀可以锁定其后指令的操作数的存储单元,该指令在指令执行期间一直有效。在多任务环境中,可以用它来保证独占其享内存,只有以下指令才可以用LOCK前缀:
XCHG,ADD,ADC,INC,SUB,SBB,DEC,NEG,OR,AND,XOR,NOT,BT,BTS,BTR,BTC
3.0 说明处理器类型的伪指令
.8086,只支持对8086指令的汇编
.186,只支持对80186指令的汇编
.286,支持对非特权的80286指令的汇编
.286C,支持对非特权的80286指令的汇编
.286P,支持对80286所有指令的汇编
.386,支持对80386非特权指令的汇编
.386C,支持对80386非特权指令的汇编
.386P,支持对80386所有指令的汇编
只有用伪指令说明了处理器类型,汇编程序才知道如何更好去编译,连接程序,更好地去检错。
九,FPU instructions(摘自fasm的帮助文档中,有时间我会反它翻译成中文的)
The FPU (Floating-Point Unit) instructions operate on the floating–point
values in three formats: single precision (32–bit), double precision (64–bit)
and double extended precision (80–bit). The FPU registers form the stack
and each of them holds the double extended precision floating–point value.
When some values are pushed onto the stack or are removed from the top,
the FPU registers are shifted, so st0 is always the value on the top of FPU
stack, st1 is the first value below the top, etc. The st0 name has also the
synonym st.
fld pushes the floating–point value onto the FPU register stack. The
operand can be 32–bit, 64–bit or 80–bit memory location or the FPU register,
it’s value is then loaded onto the top of FPU register stack (the st0 register)
and is automatically converted into the double extended precision format.
fld dword [bx] ; load single prevision value from memory
fld st2 ; push value of st2 onto register stack
fld1, fldz, fldl2t, fldl2e, fldpi, fldlg2 and fldln2 load the commonly
used contants onto the FPU register stack. The loaded constants are
+1.0, +0.0, log2 10, log2 e, pi, log10 2 and ln 2 respectively. These instructions
have no operands.
fild convert the singed integer source operand into double extended precision
floating-point format and pushes the result onto the FPU register stack.
The source operand can be a 16–bit, 32–bit or 64–bit memory location.
fild qword [bx] ; load 64-bit integer from memory
fst copies the value of st0 register to the destination operand, which can
be 32–bit or 64–bit memory location or another FPU register. fstp performs
the same operation as fst and then pops the register stack, getting rid of
st0. fstp accepts the same operands as the fst instruction and can also
store value in the 80–bit memory.
fst st3 ; value of st0 into st3 register
fstp tword [bx] ; store value in memory and pop stack
fist converts the value in st0 to a signed integer and stores the result
in the destination operand. The operand can be 16–bit or 32–bit memory
location. fistp performs the same operation and then pops the register
stack, it accepts the same operands as the fist instruction and can also store
integer value in the 64–bit memory, so it has the same rules for operands as
fild instruction.
fbld converts the packed BCD integer into double extended precision
floating–point format and pushes this value onto the FPU stack. fbstp
converts the value in st0 to an 18–digit packed BCD integer, stores the
result in the destination operand, and pops the register stack. The operand
should be an 80–bit memory location.
fadd adds the destination and source operand and stores the sum in the
destination location. The destination operand is always an FPU register,
if the source is a memory location, the destination is st0 register and only
source operand should be specified. If both operands are FPU registers, at
least one of them should be st0 register. An operand in memory can be a
32–bit or 64–bit value.
fadd qword [bx] ; add double precision value to st0
fadd st2,st0 ; add st0 to st2
faddp adds the destination and source operand, stores the sum in the destination
location and then pops the register stack. The destination operand
must be an FPU register and the source operand must be the st0. When no
operands are specified, st1 is used as a destination operand.
38 CHAPTER 2. INSTRUCTION SET
faddp ; add st0 to st1 and pop the stack
faddp st2,st0 ; add st0 to st2 and pop the stack
fiadd instruction converts an integer source operand into double extended
precision floating–point value and adds it to the destination operand.
The operand should be a 16–bit or 32–bit memory location.
fiadd word [bx] ; add word integer to st0
fsub, fsubr, fmul, fdiv, fdivr instruction are similar to fadd, have
the same rules for operands and differ only in the perfomed computation.
fsub substracts the source operand from the destination operand, fsubr
substract the destination operand from the source operand, fmul multiplies
the destination and source operands, fdiv divides the destination operand by
the source operand and fdivr divides the source operand by the destination
operand. fsubp, fsubrp, fmulp, fdivp, fdivrp perform the same operations
and pop the register stack, the rules for operand are the same as for the faddp
instruction. fisub, fisubr, fimul, fidiv, fidivr perform these operations
after converting the integer source operand into floating–point value, they
have the same rules for operands as fiadd instruction.
fsqrt computes the square root of the value in st0 register, fsin computes
the sine of that value, fcos computes the cosine of that value, fchs
complements its sign bit, fabs clears its sign to create the absolute value,
frndint rounds it to the nearest integral value, depending on the current
rounding mode. f2xm1 computes the exponential value of 2 to the power of
st0 and substracts the 1.0 from it, the value of st0 must lie in the range ?1.0
to +1.0. All these instruction store the result in st0 and have no operands.
fsincos computes both the sine and the cosine of the value in st0 register,
stores the sine in st0 and pushes the cosine on the top of FPU register
stack. fptan computes the tangent of the value in st0, stores the result in
st0 and pushes a 1.0 onto the FPU register stack. fpatan computes the
arctangent of the value in st1 divided by the value in st0, stores the result
in st1 and pops the FPU register stack. fyl2x computes the binary logarithm
of st0, multiplies it by st1, stores the result in st1 and pop the FPU
register stack; fyl2xp1 performs the same operation but it adds 1.0 to st0
before computing the logarithm. fprem computes the remainder obtained
from dividing the
G. x86有多少条汇编指令
我怀疑好多答主都没看过 ARM 汇编…
其实 ARM 比 x86 入门容易得多了。
第一历史包袱少,不会搜出一大堆抄来抄去的过时资料。SVE 指令随意变长,比 x86 一大堆过时的、定长的 SIMD 指令好用多了。
第二每条指令其实是更简单的规则的组合,大部分指令都是 cond+op+rn+rd+* 的格式,而 x86 的 binary encoding 你记得住?
第三寄存器多,写汇编很多时候都不用搞人肉寄存器分配了。理解代码也不需要人脑模拟 push 和 pop 了。
第四指令抽象度高,理解难度直线下降。dalvik 虚拟机指令翻译到 arm native code 几乎同构的它不爽?
手册是都很厚,但手册是用来查的,学习只用理解基本规则。
当然,RISC-V 比 ARM 和 x86 都更简单。
H. 如何编译linux的x86内核
Gcc编译器, Linux-2.6.29内核
步骤:
(一):清除临时文件,中间文件和配置文件等(刚从网上下载下来的文件这步可省略)。
make clean
删除大多数的由编译生成的文件、但会保留内核的配置文件.config。
make mrproper
删除所有的编译生成的文件,还有内核配置文件,再加上各种备份文件。
make distclean
mrproper删除的文件,加上编辑备份文件和一些补丁文件。
(二)选择参考配置文件
使用正在运行的内核配置文件作为参考配制文件,该配置文件在/boot目录下,使用命令
cp /boot/config-2.6.18-53.el5 .config。
(三)配置内核
配置内核有如下命令:
make config:基于文件模式的交互式配置(也就是一问一答)。
make menuconfig:基于文本模式的菜单式配置(强烈推荐)。
make oldconfig:使用已有的配置文件(.config)但是会询问新增的配置选项。
make xconfig:图形化配置(需要安装图形化系统)。
make menuconfig是最为常用的内核配置方式,使用方法如下:
1、使用方向键在各选项间移动;
2、使用“Enter”键进入下一层选单;每个选项上的高亮字母是键盘快捷方式,使用它可以快速地到达想要设置的选单项。
3、在括号中按“y”将这个项目编译进内核中,按“m”编译为模块,按“n”为不选择(按空格键也可在编译进内核、编译为模块和不编译三者间进行切换),按“h”将显示这个选项的帮助信息,按“Esc”键将返回到上层选单。
内核配置通常在一个已有的配置文件基础上,通过修改得到新的配置文件Linux内核提供了一系列可供参考的内核配置文件,位于Arch/$cpu/configs
注意:要运行make menuconfig的界面需要调整终端的窗口大小,至少为80*19。
(四)编译内核
(1):make zImage
(2):make bzImage
区别:在X86平台,在zImage只能用于小于512Kd的内核(注意是X86平台)
如需获取详细编译信息,可使用:
make zImage V=1
make bzImage V=1
编译好的内核位于arch/<cpu>/boot目录下
(五)编译内核模块
使用命令make moles
内核模块编译的时间比较长,一般需要1~2小时的时间。这些模块源于使用命令make menuconfig启动的菜单型配置界面中选择<m>的项。
(六)安装内核模块
使用命令:make moles_install,完成安装后,编译好的内核模块会从内核源代码目录拷贝至/lib/moles/2.6.29目录下。
(七)制作init ramdisk
使用cd跳动linux-2.6.29/,目录的上层目录,使用命令:mkinitrdinitrd-$version $version(mkinitrd initrd-2.6.29 2.6.29)将上一步中产生的模块目录/lib/moles/2.6.29制作成initrd-2.6.29。
提示:initrd是“initial ramdisk”的缩写,initrd是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统。在桌面或服务器Linux系统中,initrd是一个临时的文件系统。其生命周期很短,只会用作真实文件系统的一个桥梁。在没有存储设备的嵌入式系统中,initrd可以是永久的根文件系统。
Linux的众多发行版之所以使用initrd主要是为了在内核启动之后能够判断哪些硬件驱动需要加载,哪些不需要,文件系统有没有问题等,最终使得根分区能顺利加载。在scsi和sata设备上启动,usb启动盘,无盘服务器等都需要initrd来做判断,这样可以提高Linux内核的通用性。
(八)安装内核
由于Linux系统启动时,会从/boot目录下寻找内核文件与init ramdisk,所以需要将内核和initrd拷贝至/boot目录。使用命令:
cp initrd-2.6.29 /boot
cp linux-2.6.29/arch/x86/boot/bzImage /boot/vmlinuz-2.6.29
(九)修改/etc/grub.conf或者/etc/lilo.conf
为了让grub在启动时能提供一项我们自己制作的linux内核的选项,需要修改grub的配置文件/etc/grub.conf。(添加的代码为title My Linux(2.6.29)以下的)
注意:/etc/grub.conf实际上是/boot/grub/grub.conf的一个链接,因此真正的配置文件存在与/boot/grub目录下。
I. x86汇编语言的MOV指令
MOV在汇编语言中是数据传送指令。
用法如下:
mov— Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...)
mov指令将第二个操作数(可以是寄存器的内容、内存中的内容或值)复制到第一个操作数(寄存器或内存)。mov不能用于直接从内存复制到内存,其语法如下所示:
mov <reg>,<reg>
mov <reg>,<mem>
mov <mem>,<reg>
mov <reg>,<const>
mov <mem>,<const>
Examples
mov eax, ebx— 将ebx的值拷贝到eax
mov byte ptr [var], 5— 将5保存找var指示内存中的一个字节中
J. 如何编译x86的linux内核
1.清除临时文件、中间文件和配置文件。
(1) make clean
remove most generated files but keep the config
(2) make mrproper
remove all generated files + config files
(3) make distclean
mrproper + remove editor backup and patch files
2. 确定目标系统的软硬件配置情况,比如CPU的类型、网卡的型号、所需支持的网络协议等。
3.使用如下命令之一配置内核。
(1) make config
基于文本模式的交互式配置,配置时系统会逐个询问你选择Y or N ,直到配置完成。
(2) make menuconfig
基于文本模式的菜单型配置。(推荐使用)