kali-hi
Banned
- Registriert
- Sep. 2025
- Beiträge
- 760
Nabend, ich nehme noch einmal Bezug auf: https://www.computerbase.de/forum/threads/assemblerprogramm-erklaeren.2259161/ und wage einen zweiten Anlauf... Ich würde mir konstruktive Beiträge wünschen, kein Geflame, und ChatGpt-Antwort nur, wenn sie auch einen Mehrwert böten.
Das Sortierverfahren sieht in C so aus:
An sich recht simple, sortiere so lange, bis es keine Änderung mehr gab, und gib dann alle Zahlen aus (das Verfahren ist jetzt auch stabil).
Mit
also 152 Zeilen reinster Maschinencode, der wie Kraut und Rüben aussieht. Er kann ausgeführt werden mit
Diesen Assemblercode möchte ich jetzt aber lesbarer machen. Das heißt, folgende Kriterien sind wichtig:
1. Übersichtlichkeit und Verständlichkeit,
2. weniger Sprungmarken,
3. weniger Zeilen,
4. höhere Laufzeiteffizienz
Mein Ergebnis ist bislang folgendes:
Ich konnte also durch Umstellen ~ 10 Zeilen und einige Sprungmarken sparen.
Meine Frage wäre nun, ob man hier noch weiter optimieren kann, bzw. oder ob ich noch etwas übersehen habe.
Das Sortierverfahren sieht in C so aus:
C:
#include <stdio.h>
int arr[] = {3, 5, 4, 1, 9, 7, 2, 6, 8};
int n = 9;
char str[] = "%d\n";
int iteration() {
int i = 0, a, b;
while (i < n - 1) {
a = arr[i];
b = arr[i + 1];
if (a > b) {
arr[i] = b;
arr[i + 1] = a;
return 1;
}
i++;
}
return 0;
}
void print() {
int i = 0;
while (i < n) {
printf(str, arr[i]);
i++;
}
}
int main() {
while (iteration())
;
print();
return 0;
}
An sich recht simple, sortiere so lange, bis es keine Änderung mehr gab, und gib dann alle Zahlen aus (das Verfahren ist jetzt auch stabil).
Mit
gcc -S sort.c wird daraus:
Code:
.file "sort.c"
.text
.globl arr
.data
.align 32
.type arr, @object
.size arr, 36
arr:
.long 3
.long 5
.long 4
.long 1
.long 9
.long 7
.long 2
.long 6
.long 8
.globl n
.align 4
.type n, @object
.size n, 4
n:
.long 9
.globl str
.type str, @object
.size str, 4
str:
.string "%d\n"
.text
.globl iteration
.type iteration, @function
iteration:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $0, -4(%rbp)
jmp .L2
.L5:
movl -4(%rbp), %eax
cltq
leaq 0(,%rax,4), %rdx
leaq arr(%rip), %rax
movl (%rdx,%rax), %eax
movl %eax, -8(%rbp)
movl -4(%rbp), %eax
addl $1, %eax
cltq
leaq 0(,%rax,4), %rdx
leaq arr(%rip), %rax
movl (%rdx,%rax), %eax
movl %eax, -12(%rbp)
movl -8(%rbp), %eax
cmpl -12(%rbp), %eax
jle .L3
movl -4(%rbp), %eax
cltq
leaq 0(,%rax,4), %rcx
leaq arr(%rip), %rdx
movl -12(%rbp), %eax
movl %eax, (%rcx,%rdx)
movl -4(%rbp), %eax
addl $1, %eax
cltq
leaq 0(,%rax,4), %rcx
leaq arr(%rip), %rdx
movl -8(%rbp), %eax
movl %eax, (%rcx,%rdx)
movl $1, %eax
jmp .L4
.L3:
addl $1, -4(%rbp)
.L2:
movl n(%rip), %eax
subl $1, %eax
cmpl %eax, -4(%rbp)
jl .L5
movl $0, %eax
.L4:
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size iteration, .-iteration
.globl print
.type print, @function
print:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $0, -4(%rbp)
jmp .L7
.L8:
movl -4(%rbp), %eax
cltq
leaq 0(,%rax,4), %rdx
leaq arr(%rip), %rax
movl (%rdx,%rax), %eax
movl %eax, %esi
leaq str(%rip), %rax
movq %rax, %rdi
movl $0, %eax
call printf@PLT
addl $1, -4(%rbp)
.L7:
movl n(%rip), %eax
cmpl %eax, -4(%rbp)
jl .L8
nop
nop
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size print, .-print
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
nop
.L10:
movl $0, %eax
call iteration
testl %eax, %eax
jne .L10
movl $0, %eax
call print
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Debian 14.2.0-19) 14.2.0"
.section .note.GNU-stack,"",@progbits
also 152 Zeilen reinster Maschinencode, der wie Kraut und Rüben aussieht. Er kann ausgeführt werden mit
gcc sort.s -o sort und ./sort.Diesen Assemblercode möchte ich jetzt aber lesbarer machen. Das heißt, folgende Kriterien sind wichtig:
1. Übersichtlichkeit und Verständlichkeit,
2. weniger Sprungmarken,
3. weniger Zeilen,
4. höhere Laufzeiteffizienz
Mein Ergebnis ist bislang folgendes:
Code:
.file "sort.c"
.text
.globl arr
.data
.align 32
.type arr, @object
.size arr, 36
arr:
.long 3
.long 5
.long 4
.long 1
.long 9
.long 7
.long 2
.long 6
.long 8
.globl n
.align 4
.type n, @object
.size n, 4
n:
.long 9
.globl str
.type str, @object
.size str, 4
str:
.string "%d\n"
.text
.globl iteration
.type iteration, @function
iteration:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $-1, -4(%rbp)
.L1:
movl n(%rip), %eax
subl $1, %eax
addl $1, -4(%rbp)
cmpl %eax, -4(%rbp)
jge .L2
movl -4(%rbp), %eax
cltq
leaq 0(,%rax,4), %rdx
leaq arr(%rip), %rax
movl (%rdx,%rax), %eax
movl %eax, -8(%rbp)
movl -4(%rbp), %eax
addl $1, %eax
cltq
leaq 0(,%rax,4), %rdx
leaq arr(%rip), %rax
movl (%rdx,%rax), %eax
movl %eax, -12(%rbp)
movl -8(%rbp), %eax
cmpl -12(%rbp), %eax
jle .L1
movl -4(%rbp), %eax
cltq
leaq 0(,%rax,4), %rcx
leaq arr(%rip), %rdx
movl -12(%rbp), %eax
movl %eax, (%rcx,%rdx)
movl -4(%rbp), %eax
addl $1, %eax
cltq
leaq 0(,%rax,4), %rcx
leaq arr(%rip), %rdx
movl -8(%rbp), %eax
movl %eax, (%rcx,%rdx)
movl $1, %eax
jmp .L3
.L2:
movl $0, %eax
.L3:
popq %rbp
ret
.cfi_endproc
.size iteration, .-iteration
.globl print
.type print, @function
print:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $0, -4(%rbp)
.L4:
movl n(%rip), %eax
cmpl %eax, -4(%rbp)
jge .L5
movl -4(%rbp), %eax
cltq
leaq 0(,%rax,4), %rdx
leaq arr(%rip), %rax
movl (%rdx,%rax), %eax
movl %eax, %esi
leaq str(%rip), %rax
movq %rax, %rdi
movl $0, %eax
call printf@PLT
addl $1, -4(%rbp)
jmp .L4
.L5:
leave
ret
.cfi_endproc
.size print, .-print
.globl main
.type main, @function
main:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
.L6:
movl $0, %eax
call iteration
testl %eax, %eax
jne .L6
movl $0, %eax
call print
movl $0, %eax
popq %rbp
ret
.cfi_endproc
.size main, .-main
.ident "GCC: (Debian 14.2.0-19) 14.2.0"
.section .note.GNU-stack,"",@progbits
Ich konnte also durch Umstellen ~ 10 Zeilen und einige Sprungmarken sparen.
Meine Frage wäre nun, ob man hier noch weiter optimieren kann, bzw. oder ob ich noch etwas übersehen habe.