0

_FN の減算が機能しないのはなぜですか? 結果が欲しいものに一定の大きな数を追加しているようです。理由がわからない。膨大な数を出力していますが、レジスタは正しい値を保持しているため、なぜこれを行っているのかわかりません。

subl に何か特別なものがあるのか​​、それともレジスタが実際にメモリ ロケーションなどを保持しているのか疑問に思っていました。

// Pgm to 
// S. Renk 11/01


// *****************************************
// ****                                 ****
// *****************************************
    .text
    .globl _FN 

_FN:    // 
    // save old base ptr & get space for local vars
pushl %ebp
movl  %esp,%ebp

// create local vars
    subl  $12, %esp

movl 12(%ebp),%ecx
movl 8(%ebp),%ebx

pushl %ecx
pushl $FMT2
call _printf
addl $8,%esp

pushl %ebx
pushl $FMT2
call _printf
addl $8,%esp

subl %ebx,%ecx

pushl %ecx
pushl $FMT_INT
call _printf
addl $8,%esp


    // function body goes here

END:    // exit & return
// movl  -4(%ebp),%eax
leave
ret


// *******************************************
// ***********         MAIN       ************
// *******************************************

PROMPT:
.ascii "enter a number: \0"
FMT_INT:
.ascii "%d\0"
FMT2:
.ascii "My value is %d\n\0"
TEST:
.ascii "PRINT\n\0"

ANSWER:
.ascii "The answer is: %d\0"
.globl _main

// void main()
_main:  
    pushl %ebp                # save old frame ptr
movl  %esp,%ebp           # set new frame ptr & save loal var space

    // create local variable space
    subl $8, %esp

    // main body here

//prompts the user for the number to divide
pushl $PROMPT
call _printf

addl $4,%esp

//Create D1 Variable
leal -4(%ebp),%ebx #puts the address of D1 in ebx

//takes in the number to divide
pushl %ebx
pushl $FMT_INT
call _scanf

addl $8,%esp

//prompts the user for the number to divide by
pushl $PROMPT
call _printf

addl $4,%esp

//Create D2 Variable
leal -8(%ebp),%ecx #puts the address of D2 in ecx

//takes in the number to divide by
pushl %ecx
pushl $FMT_INT
call _scanf
addl $8,%esp

//tests to make sure variables are where they need to be
pushl -4(%ebp)
pushl $FMT2
call _printf
addl $8,%esp

pushl -8(%ebp)
pushl $FMT2
call _printf
addl $8,%esp

call _FN

// return
    leave
ret
4

1 に答える 1

1

2 つの printf 呼び出しを前後に追加pushl %ecx; popl %ecxして、%ecx が破棄されていることを確認します

pushl %ecx     ;; Save a copy of ecx, eg. 10
...
pushl %ecx     ;; use stack to pass value of "10" to printf
pushl $FMT2    ;; pass the string (address) to printf
call _printf   ;; during the call _printf overwrites ecx:=167838424
addl $8,%esp   ;; the parameters are cleaned from the stack

pushl %ebx     ;; same here.
pushl $FMT2    ;;
call _printf   ;; ecx is again modified, but ebx maintains its value
addl $8,%esp   ;; clean the stack (by moving stack pointer)
...
popl %ecx      ;; here's the copy of original 10 (to be used for subl)

スタック ポインターとフレーム ポインターの使用法について詳しくは、こちらを参照してください。

于 2012-11-09T23:07:38.833 に答える