2017-05-09 5 views
2

私はかなりばかげた問題を抱えていますが、どこでも解決策を見つけることはできません。32ビットコードでレジスタをインクリメントできない

メモリ(ピース(32ビット))から2つの数値を加算して、その部分和をスタックに書き込むプログラムを作成しようとしています。残念ながら、理由はわかりませんが、inc %ecxの後にループのカウンタが増加しません。 (私はgdbでテストしましたが、%ecxinc命令の直後でも0にとどまります)。

私はIntelアーキテクチャ用ですが、AT & T構文(ここでは選択肢はありません)で書いています。

.code32 

SYSEXIT = 1 
EXIT_SUCCESS = 0 

.align 32 
.data 
nr1: 
    .long 0xF0000111, 0x000B0000 
nr2: 
    .long 0x10000333, 0x000A000F 
size: 
    .long 0x00000002 

.text 
.global _start 
_start: 
mov $0, %ecx     #initialization of counter 
movl size(,%ecx,4), %edi  #moving size (amount of 32-bit pieces) to %edi 

addition: 
movl nr1(,%ecx,4), %eax #moving one piece 
movl nr2(,%ecx,4), %ebx #(from address of nr1 + (value of %ecx * 4 bytes) 

adcl %ebx, %eax     #add with carry 
push %eax      #push the result 

inc %ecx      #increment counter 
cmp %edi, %ecx     #compare %edi (==2) with counter (%ecx) 
je overflow      # if %edi == %ecx 
jmp addition     # else back to addition loop 

overflow: #in case when last sum had an overflow (CF==1) 
mov $0, %eax     
adcl $0, %eax 
push %eax 

end: 
mov $SYSEXIT, %eax 
mov $EXIT_SUCCESS, %ebx 
int $0x80 

それが起こると、将来的にこの問題を回避する方法なぜあなたも説明できるならば、私は(あなたが見ることができるように私はまだ学んでいる)、それを本当に感謝します。また、他の間違いがある場合は、教えてください。前もって感謝します。

答えて

0

あなたのコードを64ビットシステムに組み立てているようです。したがって、アセンブラのデフォルトは64ビットのバイナリになります。このようなバイナリ内のすべてのコードは64ビットコードとして実行されます。指示文

.code32 

アセンブラは32ビットコードを出力しますが、プロセッサが命令を解釈する方法は変更しません。それはあなたのコードを64ビットコードとして解釈します。アセンブラは、(プロセッサが32ビットコードとしてinterpreteます)32ビットのオブジェクトファイルを生成するようにするには、代わりにコマンドラインで特別なスイッチを渡す必要があります:

as --32 code.s 

さて、なぜincスキップさはありますか? x86プロセッサでは、32ビットモードは64ビットモードに非常に似ているので、ほとんどの命令は同じことをします。ほとんどの場合、32ビットと64ビット命令を区別するために新しい接頭語セットが導入されました。これらの新しいプレフィックスにはオペコードがないので、オペコード40〜〜(意味はinc r32dec r32)が再利用されました。 incおよびdec命令は、異なる2バイトエンコーディングで引き続き使用できます。このため、プロセッサはincをスキップし、次の命令を変更しました。

(ブートローダーの作成など)非常に奇妙なことをしない限り、.code32ディレクティブは必要ありません。それが存在することを忘れてください。システムコールが32ビットポインタのみを受け入れるので、int $0x80を64ビットコードでシステムコールするのに使用しないでください。 64ビットコードでは、システムコールにはsyscallを使用しますが、システムコール番号と呼び出し規約の両方が異なります。

+0

私が他の答えで書いたように、それは助けてくれました( '.code 32 'を取り除いた後に' push'のためのオペランドを固定することに伴い)。説明とヒントをありがとう、私にいくつかの問題を保存する必要があります。 – Newb

+1

@Newb先生が32ビットアセンブリを教えているようですが、 '--32'フラグを使って32ビットプログラムとしてアセンブルする方が良いでしょう。常に喜んで助けてください! – fuz

+0

私はおそらくその旗で回り去りますが、今のところ、何かがうまくいかなかった場合に倒れるようなものがあります。 – Newb

関連する問題