小编GJ.*_*GJ.的帖子

将小数字加载到64位x86寄存器中

在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)?

...

什么是更快,什么更经济?

optimization assembly x86-64

3
推荐指数
3
解决办法
671
查看次数

如何在汇编中以字节数的2位进行交换

*我正在使用程序集8086(x86-32)

交易非常简单,我在寄存器AL(8位)中有一个字节大小的数字,现在,我需要在寄存器中的第1位(右起第二位)和第4位(右起第五位)之间进行交换AL.

例如:如果Al有这个数字:00010000B现在它将有00000010B.

谢谢!

x86 assembly bit-manipulation

3
推荐指数
2
解决办法
1531
查看次数

x86 mov操作码反汇编

我内置了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)

有什么不同?

我怀疑拆解有问题,但无法转换上层操作码.

我所知道的是:

  • 65gs前缀
  • 48REX.W前缀
  • 8Bmov......
  • ... ???

debugging x86 assembly x86-64 disassembly

2
推荐指数
1
解决办法
1691
查看次数

Delphi标签的地址

我正在使用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)

delphi delphi-2010

2
推荐指数
1
解决办法
681
查看次数

软件生成的中断和软件生成的异常有什么区别?

我正在阅读英特尔手册 3A 第 6 章中断和异常处理。

\n\n

中断和异常分别有3个来源。

\n\n

对于软件生成的中断,它说:

\n\n
\n

INT 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
\n

INTO、INT 3 和 BOUND 指令允许在软件中生成异常。这些指令允许在指令流中的点处执行异常条件检查。例如,INT 3 会导致生成断点异常。INT\nn指令可用于模拟软件中的异常;但有一个限制。如果 INT n 为架构定义的异常之一提供向量,则处理器会生成正确向量的中断(以访问异常处理程序),但不会将错误代码推送到堆栈上。即使相关的硬件生成的异常通常会产生错误代码,情况也是如此。在处理异常时,异常处理程序仍会尝试从堆栈中弹出错误代码。由于没有推送错误代码,处理程序将弹出并丢弃 EIP(代替丢失的错误代码)。这会将返回值发送到错误的位置。

\n
\n\n

那么,有什么区别呢?似乎都利用了int n指令。如何判断一段汇编代码中是否产生异常或中断?

\n

x86 exception interrupt interrupt-handling

2
推荐指数
1
解决办法
1431
查看次数