我想知道用汇编语言开发游戏需要做些什么。例如,在游戏开发中使用汇编语言有哪些限制或优势?此外,是否有任何程序/软件帮助开发游戏的汇编语言?
发布于 2014-10-11 20:59:14
是的,事实上是有可能的。俗话说,
任何事情都是可能的,只要你用心去做。
很久以前,RollerCoaster大亨是一个相当流行的游戏,它几乎完全是用x86程序集编写的,尽管使用了一些C函数来与OS和DirectX进行接口。
然而,正如你可能想象的那样,这可能是非常痛苦的。高级语言的存在可以使事情变得更简单。我最喜欢的是,C通常用于紧凑型应用程序,并且被认为是相当低的级别。
下面是从一个简单的C函数(气泡排序,其中最简单的一个)到x64程序集的直接转换的一个例子:
C (Rosetta码):
void bubble_sort (int *a, int n) {
int i, t, s = 1;
while (s) {
s = 0;
for (i = 1; i < n; i++) {
if (a[i] < a[i - 1]) {
t = a[i];
a[i] = a[i - 1];
a[i - 1] = t;
s = 1;
}
}
}
}x64 (GCC)
bubble_sort:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-24], rdi
mov DWORD PTR [rbp-28], esi
mov DWORD PTR [rbp-8], 1
jmp .L2
.L6:
mov DWORD PTR [rbp-8], 0
mov DWORD PTR [rbp-4], 1
jmp .L3
.L5:
mov eax, DWORD PTR [rbp-4]
cdqe
lea rdx, [0+rax*4]
mov rax, QWORD PTR [rbp-24]
add rax, rdx
mov edx, DWORD PTR [rax]
mov eax, DWORD PTR [rbp-4]
cdqe
sal rax, 2
lea rcx, [rax-4]
mov rax, QWORD PTR [rbp-24]
add rax, rcx
mov eax, DWORD PTR [rax]
cmp edx, eax
jge .L4
mov eax, DWORD PTR [rbp-4]
cdqe
lea rdx, [0+rax*4]
mov rax, QWORD PTR [rbp-24]
add rax, rdx
mov eax, DWORD PTR [rax]
mov DWORD PTR [rbp-12], eax
mov eax, DWORD PTR [rbp-4]
cdqe
lea rdx, [0+rax*4]
mov rax, QWORD PTR [rbp-24]
add rdx, rax
mov eax, DWORD PTR [rbp-4]
cdqe
sal rax, 2
lea rcx, [rax-4]
mov rax, QWORD PTR [rbp-24]
add rax, rcx
mov eax, DWORD PTR [rax]
mov DWORD PTR [rdx], eax
mov eax, DWORD PTR [rbp-4]
cdqe
sal rax, 2
lea rdx, [rax-4]
mov rax, QWORD PTR [rbp-24]
add rdx, rax
mov eax, DWORD PTR [rbp-12]
mov DWORD PTR [rdx], eax
mov DWORD PTR [rbp-8], 1
.L4:
add DWORD PTR [rbp-4], 1
.L3:
mov eax, DWORD PTR [rbp-4]
cmp eax, DWORD PTR [rbp-28]
jl .L5
.L2:
cmp DWORD PTR [rbp-8], 0
jne .L6
pop rbp
ret现在,在这个时代,人们期望他们的程序能够快速运行。如果您要做任何花哨的事情或使用大量数据,则需要优化代码。使用完全优化的相同代码如下所示:
具有公共CPU的完整体系结构优化的x64 (-O3 -march=corei7;GCC):
bubble_sort:
lea eax, [rsi-2]
cmp esi, 1
lea r8, [rdi+8+rax*4]
jg .L11
rep; ret
.L11:
add rdi, 4
.L3:
mov rax, rdi
xor esi, esi
.L6:
mov edx, DWORD PTR [rax]
mov ecx, DWORD PTR [rax-4]
cmp edx, ecx
jge .L4
mov DWORD PTR [rax], ecx
mov esi, 1
mov DWORD PTR [rax-4], edx
.L4:
add rax, 4
cmp rax, r8
jne .L6
test esi, esi
jne .L3
rep; ret等一下。看起来短多了。当然。但是,你能说出哪些指令要放在哪里,它是如何重新排序指令的,还是使用哪些组合?编译器可以。
总之,在组装中编写游戏可能是一个非常糟糕的主意。更好的方法是使用编译语言(如C)来编写您的游戏,并可能在以后的组装中手工重写一到两个函数。
如果在许多常见的实例中,手写程序集的性能要优于编译器的max优化,那么也许您应该通知编译器的开发人员,这样他们就可以与您一起添加您想要的优化。这将允许您让编译器在将来不进行干预的情况下进行同样的操作。
编译器本质通常允许您在程序集中做许多事情。糟糕的是,您甚至可以使用编译器本质来编写接近纯MMX/SSE/SSSE/AVX代码,同时让编译器仍然对其进行进一步优化,很好地分配寄存器,并将其与其余代码集成。
https://stackoverflow.com/questions/26317261
复制相似问题