学习ASM还值得吗?
我知道一点,但我还没有真正使用它或者正确地学习它,因为我在汇编程序中学到的一切都可以用1/10的时间用C或C++这样的语言来完成.那么,我应该真正学习和使用ASM吗?这对我有什么好的专业吗?它会增加我的机智吗?总之,它会让我成为更好的程序员吗?
注意:我说的是像FASM或NASM这样的低级程序集,而不是像HLA(高级汇编程序)这样的程序.
我想在Windows下编写基本的程序集,我正在使用NASM,但我无法正常工作.
如何在Windows上没有C函数的帮助下编写和编译hello world?
我试图在L1缓存中获得全部带宽,以便在Intel处理器上实现以下功能
float triad(float *x, float *y, float *z, const int n) {
float k = 3.14159f;
for(int i=0; i<n; i++) {
z[i] = x[i] + k*y[i];
}
}
Run Code Online (Sandbox Code Playgroud)
这是STREAM的三合一功能.
使用具有此功能的SandyBridge/IvyBridge处理器可获得约95%的峰值(使用NASM组装).但是,除非我展开循环,否则使用Haswell I仅达到峰值的62%.如果我展开16次,我得到92%.我不明白这一点.
我决定使用NASM在汇编中编写我的函数.装配中的主循环看起来像这样.
.L2:
vmovaps ymm1, [rdi+rax]
vfmadd231ps ymm1, ymm2, [rsi+rax]
vmovaps [rdx+rax], ymm1
add rax, 32
jne .L2
Run Code Online (Sandbox Code Playgroud)
在示例12.7-12.11 中的Agner Fog的优化组装手册中,他y[i] = y[i] +k*x[i]对Pentium M,Core 2,Sandy Bridge,FMA4和FMA3 做了几乎相同的事情(但是).我设法或多或少地自己重现了他的代码(实际上他在广播时在FMA3示例中有一个小错误).除FMA4和FMA3外,他为每个处理器的表格提供指令大小计数,融合操作,执行端口.我曾试图为FMA3制作这张桌子.
ports
size ?ops-fused 0 1 2 3 4 5 6 7
vmovaps 5 1 ½ ½ …Run Code Online (Sandbox Code Playgroud) 任何人都可以给我一个关于ORG指令的全面描述吗?
何时以及为何在汇编编写的应用程序中使用它?
在x86或AMD64上使用Nasm.
有谁知道任何好的NASM或FASM教程?我正在努力学习汇编程序,但我似乎无法找到任何有用的资源.
我正在尝试将x86程序集和C链接。
我的C程序:
extern int plus_10(int);
# include <stdio.h>
int main() {
int x = plus_10(40);
printf("%d\n", x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的汇编程序:
[bits 32]
section .text
global plus_10
plus_10:
pop edx
mov eax, 10
add eax, edx
ret
Run Code Online (Sandbox Code Playgroud)
我编译并链接两个如下:
gcc -c prog.c -o prog_c.o -m32
nasm -f elf32 prog.asm -o prog_asm.o
gcc prog_c.o prog_asm.o -m32
Run Code Online (Sandbox Code Playgroud)
但是,当我运行结果文件时,出现了分段错误。
但是当我更换
流行版
与
mov edx,[esp + 4]
该程序工作正常。有人可以解释为什么会这样吗?
我想学习一些刚学过课堂基本概念的实用汇编语言.是否有推荐的体面书籍或教程(nasm等)?
我并没有试图提示英特尔与AT&T之争(无论如何,现在他们都支持英特尔语法)或者问哪一个本身"更好",我只是想知道选择其中一个的实际差异. .
基本上,当我几年前拿起一些基本的x86组件时,除了我正在阅读的那本书之外,我没有理由使用NASM - 这让我坚定但不由自主地进入了NASM阵营.从那时起,我使用汇编的原因很少,所以我没有机会尝试GAS.
请记住,它们都支持英特尔语法(我个人更喜欢),理论上至少应该生成相同的二进制文件(我知道它们可能不会,但意思不应该改变),有什么理由支持非此即彼?
是命令行选项吗?宏?非助记符关键字?或者是其他东西?
谢谢 :)
鉴于这段代码:
swap:
push ebp ; back up the base pointer,
mov ebp, esp
; push the context of the registers on the stack
push eax
push ebx
push ecx
push edx
mov eax, [ebp+8] ; address of the first parameter
mov ebx, [ebp+12] ; address of the second parameter
mov dl, [eax]
mov cl, [ebx]
mov [eax], cl
mov [ebx], dl
; restore the context of the registers from the stack
pop edx
pop ecx
pop ebx
pop eax
; …Run Code Online (Sandbox Code Playgroud)