我想用c和汇编程序代码向你展示我的程序。我也有一些问题。
这是c
中的一段代码#include <stdio.h>
void podaj_znak(int tab[], int n);
int main()
{
int tab[7] = {4, 5, 6, 2, -80, 0, 56};
printf("Przed: ");
for (int i = 0; i < 7; i++)
printf("%d ", tab[i]);
printf("\n");
podaj_znak(tab, 7);
printf("Po: %d %d %d %d %d %d %d", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6]);
printf("\n");
return 0;
}
和asm就在这里
.686
.model flat
public _podaj_znak
.code
_podaj_znak PROC
push ebp
mov ebp, esp
mov edx, [ebp+8]
mov ecx, [ebp+12]
ptl:
mov eax, [edx]
cmp eax, 0
jl minus
ja plus
mov ebx, 0
mov [edx], ebx
jmp dalej
minus: mov ebx, -1
mov [edx], ebx
jmp dalej
plus: mov ebx, 1
mov [edx], ebx
jmp dalej
dalej: add edx, 4
sub ecx, 1
jnz ptl
pop ebp
ret
_podaj_znak ENDP
END
我的问题是,如何简化/压缩代码?
编辑:发布程序的功能以及我喜欢的内容。这只是我训练和习惯组装。程序就像你从-inf到inf得到数字,当实际数字等于0时,它保持不变,当它小于0时,它被-1替换,当数字大于0,它被替换为1.事情是,我想以某种方式优化汇编程序代码,但我不知道是否甚至可以压缩它。
答案 0 :(得分:1)
不太适合这个论坛,但仍然:
对于C代码,我创建了一个PrintTab函数,它接受制表符并计算并打印表格。然后在podaj_znak调用之前和之后调用它。
对于asm代码:
答案 1 :(得分:1)
nasm语法,可能需要为其他asm进行微妙的修复,我的解决方案:
; converts values in tab into [-1, 0, 1] as sgn()
; arguments: two on stack(int tab[], int n)
; modified registers: esi, edi, eax, ebx
; "no branch" version (except loop itself)
_podaj_znak:
mov esi,[esp+4] ; tab ptr
mov eax,[esp+8] ; count
xor ebx,ebx
lea edi,[esi+eax*4] ; tab.end() ptr
sgn_loop:
lodsd ; eax = [ds:esi], esi += 4
; change eax to [-1, 0, 1] by sgn(eax)
test eax,eax
setnz bl
sar eax,31
or eax,ebx
; overwrite original value with sgn() result
cmp esi,edi ; test if end of tab was reached
mov [esi-4],eax
jb sgn_loop
ret
然后为了好奇心谷歌搜索互联网(只是循环部分不同),3指令版本(我是4):
...
; modifies also edx in this variant
sgn_loop:
lodsd ; eax = [ds:esi], esi += 4
; set edx to [-1, 0, 1] by sgn(eax)
cdq
cmp edx,eax
adc edx,ebx
; overwrite original value with sgn() result
cmp esi,edi
mov [esi-4],edx
jb sgn_loop
ret
这两种变体都是无分支的,因此它们应该具有优于任何分支变体的性能(但我不打算对其进行分析)。
答案 2 :(得分:0)
可以通过仅调用一次mov [edx], ebx
来优化程序集,如下所示:
ptl:
mov eax, [edx]
cmp eax, 0
jl minus
ja plus
mov ebx, 0 ; only set to 0
jmp dalej
minus: mov ebx, -1 ; only set to -1
jmp dalej
plus: mov ebx, 1 ; only set to 1
jmp dalej
dalej: mov [edx], ebx ; update the array[edx]
add edx, 4
sub ecx, 1
jnz ptl