我想知道用汇编语言开发游戏需要什么。例如,在游戏开发中使用汇编语言有哪些限制或优势?另外,有没有任何程序/软件可以帮助用汇编语言开发游戏?
答案 0 :(得分:6)
是的,实际上它是可能的。俗话说,
如果你想到的话,一切皆有可能。
一段时间以来相当受欢迎的游戏RollerCoaster Tycoon几乎完全是用x86程序集编写的,尽管有一些C函数用于与OS和DirectX接口。
然而,正如您可能想象的那样,这可能会非常痛苦。存在更高级别的语言以使事情更容易。我最喜欢的C
通常用于接近金属的应用程序,被认为是相当低的水平。
这是一个从简单的C函数(冒泡排序,其中最简单的一个)直接转换为x64程序集的示例:
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;
}
}
}
}
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
现在,在这个时代,人们希望他们的程序能够快速运行。如果您要做任何花哨的事情或使用大量数据,您需要优化代码。以下是完全优化的相同代码:
-O3 -march=corei7
; Godbolt 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之类的编译语言来编写游戏并且可能稍后在装配中手动重写一个或两个函数是一个更好的主意。
如果确实存在很多常见的实例,您的手写程序集通过最大优化来优于编译器,那么您可能应该通知该编译器的开发人员,以便他们可以与您一起添加您想到的优化。这将允许您让编译器在未经您干预的情况下执行相同操作。
编译器内在函数通常允许您执行许多在汇编中执行的操作。地狱,您甚至可以使用编译器内在函数编写接近纯MMX / SSE / SSSE / AVX代码,同时让编译器进一步优化它,很好地分配寄存器,并将其与其余代码集成。