此循环在英特尔Conroe/Merom上每3个周期运行一次,imul按预期方式在吞吐量方面存在瓶颈.但是在Haswell/Skylake上,它每11个循环运行一次,显然是因为setnz al它依赖于最后一个循环imul.
; synthetic micro-benchmark to test partial-register renaming
mov ecx, 1000000000
.loop: ; do{
imul eax, eax ; a dep chain with high latency but also high throughput
imul eax, eax
imul eax, eax
dec ecx ; set ZF, independent of old ZF. (Use sub ecx,1 on Silvermont/KNL or P4)
setnz al ; ****** Does this depend on RAX as well as ZF?
movzx eax, al
jnz .loop ; }while(ecx);
Run Code Online (Sandbox Code Playgroud)
如果setnz al …
假设我声明了以下内容:
section .bss
buffer resb 1
Run Code Online (Sandbox Code Playgroud)
这些说明如下:
mov al, 5 ; mov-immediate
mov [buffer], al ; store
mov bl, [buffer] ; load
mov cl, buffer ; mov-immediate?
Run Code Online (Sandbox Code Playgroud)
我是否理解bl将包含值5,并且cl将包含变量的内存地址section .text?
我对两者之间的差异感到困惑
buffervsmov cl, buffer 更新:阅读回复后,我认为以下摘要是准确的:
假设声明mov cl, [buffer]存在于mov edi, array.我的理解是:
edi将第0个数组索引的内存地址放入mov byte [edi], 3.add edi, 3 将VALUE 3放入数组的第0个索引中edi,mov al, [array]现在包含数组第3个索引的内存地址al将DATA置于第零个索引中mov al, [array+3].al将DATA放在第三个索引处mov [al], …write(1,"hi",3)在linux上反汇编,gcc -s -nostdlib -nostartfiles -O3结果如下:
ba03000000 mov edx, 3 ; thanks for the correction jester!
bf01000000 mov edi, 1
31c0 xor eax, eax
e9d8ffffff jmp loc.imp.write
Run Code Online (Sandbox Code Playgroud)
我不是到编译器的开发,但由于移动到这些寄存器的每一个值是恒定的和已知的编译时间,我很好奇,为什么不GCC使用dl,dil和al来代替.也许有人会说,此功能不会让任何性能上的差异,但有一个在之间的可执行文件的大小有很大的区别mov $1, %rax => b801000000,并mov $1, %al => b001当我们谈论数千寄存器的程序访问.如果软件的优雅部分不仅体积小,它确实会对性能产生影响.
有人可以解释为什么"海湾合作委员会决定"它无所谓?
我读到该MOV指令不能为其两个操作数都有内存位置.
喜欢:MOV [0012H], [0016H]不允许.
为什么这样?
其他指令可以为其两个操作数设置内存位置吗?
我正在使用 16 位 NASM 程序集,但存在无法构建代码的问题。错误发生在此处的所有 MOV 行上:
section .bss
x_coord RESB 8 ; [x_coord] is the head, [x_coord+2] is the next cell, etc.
y_coord RESB 8 ; Same here
pixel_x RESB 2 ; Storage for calculations
pixel_y RESB 2 ; Storage for calculations
...
MOV [pixel_x], [x_coord]
MOV [pixel_y], [y_coord]
CALL DrawPixel
MOV [pixel_x], [x_coord+2]
MOV [pixel_y], [y_coord+2]
CALL DrawPixel
MOV [pixel_x], [x_coord+4]
MOV [pixel_y], [y_coord+4]
CALL DrawPixel
MOV [pixel_x], [x_coord+6]
MOV [pixel_y], [y_coord+6]
CALL DrawPixel
Run Code Online (Sandbox Code Playgroud)
我读到这是因为汇编程序不知道变量的大小。我尝试MOV [pixel_x], byte …
我对装配很新,并且有一些非常基本的问题.
这四个命令有什么区别?
mov ebx, eax
mov [ebx], eax
mov ebx, [eax]
mov [ebx], [eax]
Run Code Online (Sandbox Code Playgroud)
他们说括号的意思是"得到地址的价值".但那么,第一线真正做到了什么呢?它不会将eax的价值转移到ebx吗?如果是这样,那么括号的重点是什么?
我想知道这是否允许组装
movl (%edx) (%eax)
Run Code Online (Sandbox Code Playgroud)
我猜想它会访问第一个操作数的内存,然后放入第二个操作数的内存,类似* a = * b,但是我没有看到任何处理此类的示例,因此我猜想它是不允许的。另外,有人告诉我这是不允许的
leal %esi (%edi)
Run Code Online (Sandbox Code Playgroud)
这是为什么?最后,还有其他类似的功能我不应该被禁止。
org 100h
mov ah, 9
mov dx, str1
mov byte [str1+2], [char]
int 21h
mov ah, 4Ch
int 21h
str1 db 'String$'
char db "o"
Run Code Online (Sandbox Code Playgroud)
为什么NASM会给我这个错误信息:
第5行出错:操作码和操作数的组合无效
mov byte [str1+2], [char]
Run Code Online (Sandbox Code Playgroud)
在这一行我试图将存储的字节移动*char到地址*str1+2.