2016-10-26 3 views
2

Schreiben Sie eine ARM-Funktion (Subroutine), um die Anzahl der ungeraden Ganzzahlen in einem Integer-Array zu zählen. Die Funktion Signatur ist:Suchen nach ungeraden Zahlen in Assembly

int numodd(int array[], int size) ; 

wobei: int array [] auf die ARM-Funktion als ein Zeiger auf das erste Element der Integer-Array übergeben wird, und int size wird als Wert übergeben, und die Anzahl der Elemente im Array.

Der Quellcode C-Sprache ist:

#include <stdlib.h> 
#include <stdio.h> 

extern int numodd(int array[], int size) ; 

int main(int argc, char * argv[]) 
{ 
    int numarray[] = { 2, 3, 1025, 3024, 4057, -3, -1025, -3578 } ; 
    int size = sizeof(numarray)/sizeof(int) ; 
    int result ; 

    result = numodd(numarray, size) ; 
    printf("Number of odd numbers: %d\n", result) ; 

    exit(0) ; 

} 

Assembly Code (bisher):

 .global numodd 
     .text 
numodd: stmfd sp!,{v1-v6,lr} 
     mov a3, #0 
elop: ldr a4, [a1], #4 
     tst a4, #1 
     beq odd 
     subs a2, a2, #1 
     bne elop 
odd: add a3, a3, #1 
     bne elop 
     mov a1, a3 
     ldmfd sp!,{v1-v6,pc} 
     .end 
+2

Was ist Ihre Frage? Erfüllt dieser Code, was Sie erwarten? Siehe [fragen]. Wenn dies nicht der Fall ist, ist es normalerweise am besten, wenn Sie es in einem Debugger durchgehen. –

Antwort

2

Ich bin nicht sicher, wenn Sie nur die extra subs vergessen haben, oder wenn Sie ARM gedacht hatte Branch Delay Slots, aber Sie verringern nur a2 im "gerade" Fall.

Beachten Sie, dass beq odd unnötig ist, da Sie stattdessen bedingte Ausführung verwenden könnten, was wird effizienter:

tst a4, #1 
    addne a3, a3, #1  @ if (a4 & 1) a3++ 
    subs a2, a2, #1 
    bne elop 
    mov a1, a3 
    ldmfd sp!,{v1-v6,pc} 
+0

@Micheal - welche ARM-Version ist das? – InfinitelyManic

+1

@InfinitelyManic: Es ist vor-einheitliche Syntax, wenn das ist, was Sie fragen. Ich folgte einfach der Syntax, die das OP verwendete (sieht aus wie Armasm, für ARMv4 oder möglicherweise etwas noch älteres). – Michael

+0

Danke Mann. Es hat perfekt funktioniert. Ich werde darüber nachlesen müssen, um ein besseres Verständnis für das nächste Mal zu bekommen. –

0

Für die Zukunft ein ARMv8 Makro prime der Pumpe.

// isOdd 
.macro isOdd num 
.isOdd\@: 
push2 x1, xzr 
     mov x1, \num 
     ands x0, x1, 1   // if result is True then subject bit is set 
     cset x0, ne    // ne = Z flag not set; 1 AND 1 == 1 so clears Z flag; so set x0 to 0 if even num 
pop2 x1, xzr 
.endm 
Verwandte Themen