2016-06-23 10 views
0

アセンブリ言語のコーディングを学習しました。x86アセンブリ言語でのストレージと文字列の操作

Q:符号付き整数を表す文字列を2の補数の値に変換し、その結果をリトルエンディアンの順番でメモリの連続した場所に格納します。

たとえば、2の補数が64ビットであると仮定すると、1 = 0xFFFFFFFFFFFFFFFEです。私はGDBで

  .data 
S: .string "-149" 
Result:  .quad 

      .text 
      .globl main 

main: 
    mov  S,%rax 
    cmp  %rax,0 
    jl  positive 
    sub  %rax,%rax 
    not  S 
    add  S,%rax 
    sub  $30,%rax 
    not  %rax 
    add  $1, %rax 
    mov  %rax,Result 

positive: 
    sub  $30,%rax 
    not  %rax 
    add  $1,%rax 
    mov  %rax,Result 

ff6b 0xffffのFFFF FFFFを生じるはずである私のコード内の番号-149をやった、格納されている文字列の整数の値はこれです。

(gdb) x/24xb &S 
0x601038: 0x2d 0x31 0x34 0x39 0x00 0x00 0x00 0x00 
0x601040: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x601048: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 

私は-149に任意の計算をやってみたかった場合、私は何とかメモリ内のこれらの場所にアクセスする必要があるだろう - どのように私はこれをやって行くのですか?

4が10の場所にあることがわかっている場合は、10を掛けて40を取得し、9を追加して1x100を追加して100を取得し、それを追加することもできます。

計算にはどのようにアクセスすればよいですか?

+2

他の部分も釘付けにしていないようです。私たちはここでデバッグの質問に答えることはできません、正確な問題が何であるかを明確にしてください。連続した "場所"の部分は事実上明確ではありません。x86はリトルエンディアンで、処理する必要がある数値のサイズ(ビット数)に応じて、その要求はメモリに格納されます。 –

+0

ありがとうMargaret、具体的には、.stringに保存された符号付き整数値に論理演算子を適用する方法については疑問があります。 –

答えて

2

計算にはどのようにアクセスすればよいですか?

文字列は、連続した文字としてメモリに格納されます。 ASCIIの場合(UTF-8ではなく)、各文字は1バイトです。

movzbl 2(%rsi), %eaxのように、バイトロード/ストアを使用して一度に1つずつアクセスして、rsiが文字列の先頭を指している場合は3番目の文字を取得できます。

または、最後の文字(10進数で一の位)に%rdiポイントなら、imul $10, -1(%rdi), %ecxは、最後から2番目の文字に加えて、その場所-値に%clを設定します。 (そして、%ecxの上のバイトをゴミ箱に入れてください; movzxを最初にロードしてから乗算するのがおそらく良いでしょう)This does work, though, to get the low 8 bits correct)。

複雑さのスペクトルのもう一方の端で、これを見てくださいSSE4.1 IPv4 dotted-quad string to 32bit integer converter。具体的には、シャッフル後の小数点以下のプレースメント部分を[ ..., 100, 10, 1 ]のベクトルで(_mm_maddubs_epi16)を使用してプレース・バリューと水平加算の1つのステップを適用し、次にphaddwを水平方向にドット付きの各数字クワッド。

またHow to implement atoi using SIMD?

も、他のリンクのロットのタグのwikiを参照してください。

+0

はい:「ASCIIの場合(UTF-8でない場合)...」文字セットとエンコーディングを指定しなくても、文字列値を指定することはできません。 @Egyptian_Coderそれを送り返す。 –

+0

@TomBlodget:asmの宿題では、ASCIIと見なすことができます。この特定のケースでは、10進数であるはずです。つまり、UTF-8のASCIIサブセットです。私は、文字列を扱う "通常の"(簡単な)方法は、実際にUTF-8をasmで処理する必要があるかどうかを知るべきではないという提案としてではなく、1バイトあたり1バイトと仮定するという警告としてこの文章を書いています。 –

-1

まあ、これはコンパイルされないことも期待しています(たとえば、cmp %rax,0はAT & T構文の有効な組み合わせではありません。これはIntelの構文のようです)。

not Sのように意味がないものがいくつかありますが、それはどうすると思いますか?あなたがバイトptrとして注釈を付けると、それは '<'文字を反転させるでしょう(なぜ実際には '<'とS文字列の '>'が私を混乱させるのでしょうか)。

などなど...

したがって、最初の、そしてデバッガで開き、それをコンパイルしようとする命令でステップ命令、およびCPUのレジスタとメモリと、命令のリファレンスガイドを見続ける...それがするまで意味があります...時間がかかるかもしれませんが、実際にはそれほど長くないかもしれません。

+1

'cmp%rax、0 'は、絶対アドレッシングモードとの比較です。 'cmp'は、第1オペランドまたは第2オペランドとしてメモリオペランドとともに使用できるので、アセンブルする必要がありますが、オペレータが望んでいたものではありません。 –

+2

一般的な回答でサイトを汚染しないでください。完全なものを提供するか、質問にコメントするか、回答できないものとしてフラグを立てます。 –

関連する問題