在64位x86 CPU下,我们通常将数字-1加载到寄存器中,如:
mov rdx, -1 // 48BAFFFFFFFFFFFFFFFF
Run Code Online (Sandbox Code Playgroud)
...这个操作码需要10个字节.
另一种方式是:
xor rdx, rdx // 4831D2
dec rdx // 48FFCA
Run Code Online (Sandbox Code Playgroud)
...这个操作码只需要6个字节.
编辑:
正如JensBjörnhager所说(我已经测试过)xor edx, edx操作码应该清除整个rdx寄存器:
xor edx, edx // 31D2
dec rdx // 48FFCA
Run Code Online (Sandbox Code Playgroud)
...这个操作码只需要5个字节.
编辑:
Alex找到另一个解决方案
mov rdx, -1 // 48C7C2FFFFFFFF
Run Code Online (Sandbox Code Playgroud)
...这个操作码只需要7个字节.但是如何告诉编译器使用更短的操作码(不使用DB)?
...
什么是更快,什么更经济?
*我正在使用程序集8086(x86-32)
交易非常简单,我在寄存器AL(8位)中有一个字节大小的数字,现在,我需要在寄存器中的第1位(右起第二位)和第4位(右起第五位)之间进行交换AL.
例如:如果Al有这个数字:00010000B现在它将有00000010B.
谢谢!
我内置了IDE x86 debbuger,它拆解了这个:
第一种情况:
65 48 8B 05 30 00 00 00
mov rax,gs:[rel $00000030]
Run Code Online (Sandbox Code Playgroud)
第二种情况:
65 48 8B 04 25 30 00 00 00
mov rax,gs:[+$0030]
Run Code Online (Sandbox Code Playgroud)
有什么不同?
我怀疑拆解有问题,但无法转换上层操作码.
我所知道的是:
65是gs前缀48是REX.W前缀8B是mov......我正在使用Delphi pascal进行简单的PIC18 MCPU助记符仿真.是的,我打算使用Delphi IDE.我能够模拟任何asm指令,但它会在标签处停止.在某些情况下,我需要知道Delphi标签的地址.是否有可能将标签转换为指针变量?
在我的例子中?
procedure addlw(const n:byte); //emulation of mcpu addlw instruction
begin
Carry := (wreg + n) >= 256;
wreg := wreg + n;
Zero := wreg = 0;
inc(CpuCycles);
end;
procedure bnc(p: pointer ); //emulation of mcpu bnc instruction
asm
inc CpuCycles
cmp byte ptr Carry, 0
jnz @exit
pop eax //restore return addres from stack
jmp p
@exit:
end;
Run Code Online (Sandbox Code Playgroud)
// MCPU ASM代码的仿真
procedure Test;
label
Top;
var
p: pointer;
begin
//
Top:
addlw(5); //emulated mcpu addlw …Run Code Online (Sandbox Code Playgroud) 我正在阅读英特尔手册 3A 第 6 章中断和异常处理。
\n\n中断和异常分别有3个来源。
\n\n对于软件生成的中断,它说:
\n\n\n\n\nINT n 指令允许通过提供中断向量号作为操作数从软件内部生成中断。例如,INT 35 指令强制隐式调用中断 35 的中断处理程序。从 0 到 255 的任何中断向量都可以用作该指令中的参数。然而,如果使用处理器 xe2x80x99 预定义的 NMI 向量,则处理器的响应将与以正常方式生成的 NMI 中断的响应不同。如果在此指令中使用向量号 2(NMI\n 向量),则会调用 NMI 中断处理程序,但不会激活处理器\xe2\x80\x99s NMI 处理硬件。\n 软件中生成的中断INT n 指令不能被 EFLAGS 寄存器中的 IF 标志屏蔽。
\n
对于软件生成的异常,它说:
\n\n\n\n\nINTO、INT 3 和 BOUND 指令允许在软件中生成异常。这些指令允许在指令流中的点处执行异常条件检查。例如,INT 3 会导致生成断点异常。INT\nn指令可用于模拟软件中的异常;但有一个限制。如果 INT n 为架构定义的异常之一提供向量,则处理器会生成正确向量的中断(以访问异常处理程序),但不会将错误代码推送到堆栈上。即使相关的硬件生成的异常通常会产生错误代码,情况也是如此。在处理异常时,异常处理程序仍会尝试从堆栈中弹出错误代码。由于没有推送错误代码,处理程序将弹出并丢弃 EIP(代替丢失的错误代码)。这会将返回值发送到错误的位置。
\n
那么,有什么区别呢?似乎都利用了int n指令。如何判断一段汇编代码中是否产生异常或中断?
assembly ×3
x86 ×3
x86-64 ×2
debugging ×1
delphi ×1
delphi-2010 ×1
disassembly ×1
exception ×1
interrupt ×1
optimization ×1