1

このアセンブリ コードを C に変換しようとしていますが、助けが必要です。whileループと関係がありますが、whileループで何が起こるかわかりません。私はしばらくそれを見てきましたが、「while(something =! null)」が含まれていると確信していますが、コードが「movl」を %eax に実行するとどうなるかわかりません。

このセクションは、コンパイルされた x86 アセンブリ コードです。

whilecode:
        pushl   %ebp
        movl    %esp, %ebp
        jmp     .L20
.L22:
        movl    8(%ebp), %eax
        movl    16(%eax), %eax
        movl    %eax, 8(%ebp)
.L20:
        cmpl    $0, 8(%ebp)
        je      .L21
        movl    8(%ebp), %eax
        movl    4(%eax), %eax
        cmpl    12(%ebp), %eax
        jne     .L22
.L21:
        cmpl    $0, 8(%ebp)
        setne   %al
        movzbl  %al, %eax
        popl    %ebp
        ret

これはノードの定義です:

typedef enum {CHAR,SHORT,INT} Type;

typedef struct node {
  Type   thetype;
  int     data;
  void   *opaque;
  struct node *ptr1, *ptr2;
} Node;

これは、while ループの関数定義です。

/* a while loop */
int whilecode(Node *somenode, int data)
{
  // FIX ME
  return 0;
}
4

2 に答える 2

5

アセンブリが何をするかについてのコメント:

whilecode:
    pushl   %ebp            // save caller's frame pointer
    movl    %esp, %ebp      // set up our frame pointer
                            // no local variables set up
    jmp     .L20            // jump to the entry point of the function body

.L22:                       // NOT the beginning of the function -- probably a loop body
    movl    8(%ebp), %eax   // %eax = first argument
    movl    16(%eax), %eax  // %eax = %eax->fifth field
    movl    %eax, 8(%ebp)   // first argument = %eax
.L20:
    cmpl    $0, 8(%ebp)     // compare first argument to 0
    je      .L21            // branch to exit if they're equal 
    movl    8(%ebp), %eax   // %eax = first argument
    movl    4(%eax), %eax   // %eax = %eax->second field
    cmpl    12(%ebp), %eax  // compare %eax to second argument
    jne     .L22            // loop if not equal
.L21:
    cmpl    $0, 8(%ebp)     // compare first argument to 0
    setne   %al             // set %al = 1 if they're not equal (0 otherwise)
    movzbl  %al, %eax       // zero extend %al to %eax
    popl    %ebp            // restore the callers stack frame
    ret

これで構造体定義とプロトタイプができたので、最終的には次のようになります。

int whilecode(Node *somenode, int data)
{
    while (somenode != 0 && somenode->data != data)
        somenode = somenode->ptr2;
    return somenode != 0;
}

特定のデータ値を含むノードのリンク リストを検索し、見つかった場合は true を返します。

于 2013-04-28T05:17:24.247 に答える
0

修繕

whilecode:
        pushl   %ebp         `Push EBP to stack`
        movl    %esp, %ebp   `EBP = ESP`
        jmp     .L20         `goto L20`
.L22:
        movl    8(%ebp), %eax  `EAX = (EBP+8)`
        movl    16(%eax), %eax `EAX = (EAX+16)`
        movl    %eax, 8(%ebp)  `(EBP+8) = EAX`
.L20:
        cmpl    $0, 8(%ebp)
        je      .L21           `if (EBP+8) == 0 goto L21`
        movl    8(%ebp), %eax  `EAX = (EBP+8)`
        movl    4(%eax), %eax  `EAX = (EAX+4)`
        cmpl    12(%ebp), %eax 
        jne     .L22           `if (EBP+12) != EAX goto L22`
.L21:
        cmpl    $0, 8(%ebp)    
        setne   %al            `if 0 != (EBP+8) Sets the byte in the AL to 1`
        movzbl  %al, %eax      `EAX = AL (zero ext)`
        popl    %ebp           `POP from stack to EBP (recover it)`
        ret                    `return`

EBP、ESP、EAX は 32 ビットレジスタ、AL は 8 ビットレジスタです。

(EBP+8) は、EBP のアドレスに 8 バイトを加えた値です。

それに従うだけで、コードを理解できます。申し訳ありませんが、時間がありません。頑張ってください!

于 2013-04-27T21:12:14.253 に答える