我正在编写一个简单的汇编程序,当然,它的目的是尽可能快.但是,位于最嵌套循环中的某个部分看起来并不"正确",我相信有可能提出更聪明,更快速的实现,甚至可能不使用条件跳转.代码实现了一个简单的事情:
if rax < 0 then
rax := 0
else if rax >= r12 then
rax := r12 - 1
这是我天真的实施:
cmp rax, 0
jge offsetXGE
mov rax, 0
jmp offsetXReady
offsetXGE:
cmp rax, r12
jl offsetXReady
mov rax, r12
dec rax
offsetXReady:
Run Code Online (Sandbox Code Playgroud)
任何想法都是受欢迎的,即使是那些使用MMX和一些掩盖技巧的想法.
编辑:回答评论中的一些问题 - 是的,我们可以假设r12> 0但rax可能是负数.
我正在分析一系列x86指令,并对以下代码感到困惑:
135328495: sbb edx, edx
135328497: neg edx
135328499: test edx, edx
135328503: jz 0x810f31c
Run Code Online (Sandbox Code Playgroud)
我了解这sbb相当于以des = des - (src + CF)某种方式-CF输入的第一条指令edx。然后它negtive -CF变成CF,test是否CF等于零?
但是请注意,不要jz检查标志!那么上述代码序列基本上想做什么?这是合法的指令序列,由version 产生。ZFCFx86g++4.6.3
该C++代码实际上来自botan项目。您可以在此处找到总体汇编代码(Botan RSA解密示例)。反汇编代码中有很多这样的指令序列。
是否可以使用这些指令获得等于1的符号标志?
movzx ecx, byte ptr[eax]
and ecx, 8000000Fh
jns short loc_401073
Run Code Online (Sandbox Code Playgroud)
寄存器和8000000Fh and之间有一个ecx.In ecx可以是00h-FFh范围内的数字,但我不确定是否可以得到SF = 1.有人能帮助我吗?
累加器寄存器是一个保存临时值的寄存器。只有 EAX、AX、AL 寄存器是累加器。
据我所知,BX、CX、DX 和扩展版本可以保持永久值。那么,为什么我们使用 EAX、AX、AL 寄存器作为累加器呢?
什么是蓄能器?
我学到了一个地址,两个地址和三个地址指令,但是现在我想知道x86使用什么样的地址指令?
我最近开始研究汇编代码,我正在尝试重新编码一些基本的系统函数来掌握它,我目前仍然在我的0x0上遇到了一个分段错误strchr.
section .text
global strchr
strchr:
xor rax, rax
loop:
cmp BYTE [rdi + rax], 0
jz end
cmp sil, 0
jz end
cmp BYTE [rdi + rax], sil
jz good
inc rax
jmp loop
good:
mov rax, [rdi + rcx]
ret
end:
mov rax, 0
ret
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何使用GDB调试它,我遇到的文档非常有限或难以理解.
我在C中使用以下主要测试
extern char *strchr(const char *s, int c);
int main () {
const char str[] = "random.string";
const char ch = '.';
char *ret;
ret = strchr(str, ch);
printf("%s\n", ret); …Run Code Online (Sandbox Code Playgroud) 写下下面几行是什么意思?
OR AX,AX
JGE LABEL
Run Code Online (Sandbox Code Playgroud)
据我所知,OR 不是比较运算符。并且,只有当我在 CMP 的任何比较过程之后使用了诸如“JGE/JE/JL”之类的分支语句时,才能使用它们。
我想检查I放入rax寄存器的值是否为负数或空 8 字节值(long intC 中的负数)。
它让我检查rax寄存器中的 64 位是否对应于有符号位值。
经过研究,我发现如果我们将base10中的-86之类的值的每一位反转并加1,我们得到反转值86。
基于此,负反转值在位方面将小于负值。
我正在x86_64 Linux上的NASM 中构建和运行代码。
我正在应用以下代码,当I为负时显示一条消息:
section .data
msg db "I is negative", 0
section .text
global main
extern printf, exit
%define I 9
main:
mov rax, I
; Invert the bits into rax
xor rax, 0xFFFFFF
inc rax
mov rbx, I
cmp rax, rbx
jl EXIT
; Display message when I is negative
lea rdi, [msg]
xor …Run Code Online (Sandbox Code Playgroud) 我了解的是,指令融合有两种类型:
微操作是指可以在1个时钟周期内执行的操作。如果几个微操作融合在一起,我们将获得一个“指令”。
如果融合了多条指令,我们将获得宏操作。
如果几个宏操作融合在一起,我们将获得宏操作融合。
我对么?
我有以下代码:
or edx,edx (0 Or 0 would equal 0)
jz InvalidDivisor
Run Code Online (Sandbox Code Playgroud)
如果我将代码更改为:
AND edx,edx (0 and 0 would equal 0)
jz InvalidDivisor
Run Code Online (Sandbox Code Playgroud)
两种方法都不能用于检查产品是否为 0?
我可以使用 GCC 将汇编代码文件转换为可重新分配的文件。
gcc -c source.S -o object.o -O2
Run Code Online (Sandbox Code Playgroud)
优化选项是否有效?我可以期望 GCC 优化我的汇编代码吗?
assembly ×10
x86 ×9
flags ×2
nasm ×2
accumulator ×1
c ×1
cpu ×1
disassembly ×1
emu8086 ×1
gcc ×1
intel ×1
masm ×1
optimization ×1
unix ×1
x86-64 ×1