2012-03-10 20 views
3

これはいくつかの宿題の助けですが、私は過去のようには見えない特定の問題です。引数を渡すC - > NASM - > C

16進数の文字列を受け取るプログラムを作成しようとしていますが、16進文字列の10進値を与えるアセンブラ関数を呼び出しています。そのアセンブラ関数は、各文字が正当なHEX値であることを確認するCの "checker"関数を呼び出します。

私の質問は、アセンブラでEBXレジスタを取って、それを文字を必要とするC関数に正しく渡す方法です。私はアセンブラからCに適切に渡すことができないようです。私はここにポインタを誤って渡していますか?私はまた、私の人生がEBXから個々のキャラクターをバイトに分解してもらうことはできないようです。

文字が無効な場合は-1が返されます。進数の文字列を使用して最大4桁の進整数を入力してください

::私は何のために願っています

FBE あなたは、入力された:FBE FBE - F - 15

を私は何を得ます: 進数の文字列を使用して最大4桁の進整数を入力してください:FBE あなたが入力された:FBE FBE - Mを - -1

EDIT:チェックデジットの機能を割り当てに従ってのみ、個々の文字を取る必要があります。だから私は完全な機能のためにNASMの主要な機能の文字列を分割します。まだそれが一度に文字一回で動作するように取得しようとしている。..

C:

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    char input[255]; 
int dec_value; 

while (1) 
{ 
    printf ("Please enter a maximal 4 digit hex integer using a string of hex digits: "); 
    scanf ("%s",input); 
    if (strlen(input) <= 4) 
    { 
     break; 
    } 
    printf ("The string is too long!\n"); 
} 

printf ("You entered: "); 
printf ("%s\n",input); 
extern int hex2dec(char[]); 
dec_value = hex2dec(input); 
printf ("%i",dec_value); 
if (dec_value == -1) { 
    printf ("There's an invalid character!\n"); 
} 
else { 
    printf ("Decimal value of character %s is:%d \n", input, dec_value); 
}  
return 0; 
} 

int checkdigit (char hex) 
{ 
    printf (" - %c - ", hex); 
    if ((hex <= 70 && hex >= 65) || (hex >= 48 && hex <= 57)) { 
     if (hex >= 65) { 
      printf ("Letter"); 
      return ((int) (hex-'A'+10)); 
     } 
     else { 
      printf ("Number"); 
      return hex - 48; 
     } 
    } 
    return -1; 
} 

NASM:

segment .data 
segment .text 
global hex2dec 
extern checkdigit, printf 

hex2dec:   
    push EBP 
    mov  EBP,ESP 
    push EDX 
    push EBX 

    mov  EDX,0D   ; 0 EDX 
    xor  EBX,EBX 
    mov  EBX, DWORD [EBP+8] ; copy the string to EDX 

    push EBX 

    call printf  ; print whole string 
    call checkdigit  ; pass character to interpret 

    add  ESP,4    ;on return clear the stack,       
    ;the value is in EAX 
    pop  EBX  ;restore EBX   
    pop  EDX  ;restore EDX 
    pop  EBP 
    ret 

答えて

1

Chris Doddが正しいです - ポインタ(32ビットのバイト)の代わりにchar(8ビットのバイト)ビット量)。

これまでのところ、EDXで何もしていないようです。また、スタックからその値をロードする前に、EBXを0にクリアする必要はありません( "a = 12; a = 65;と同じです。最初の割り当ては直ちに破棄されるため、無関係です)。

とにかく、文字列へのポインタをEBXにロードしました。 EBXが指す8ビットのバイトをロードします。これの構文は次のような[EBX]です:

mov EDX, [EBX] 

これは、EDXが32ビットレジスタであるため、4バイトをロードします。あなただけの最初のバイトをしたいので、EDXの下位8ビット(DL)のターゲットレジスタを指定します。

mov DL, [EBX] 

上記の命令は、底部のみ8を上書きするので、それはあなたがすでに0にEDXをクリア良いこと(ですビット)。この時点で、EDXに処理したいバイトが含まれているので、EBXの代わりにEDXをスタックに押します。

これがx86アセンブリの一般的な理解を広げてくれたらと思います。

+0

ありがとう!コードクラフトのビットのためにお詫び申し上げます。私が実際にポインタや値を渡しているかどうかはわかりませんでした。それはそんなに説明します。そして、それは、私があまりにも長い間プログラミングしてきたときにいくつかのものを解明するのに役立ちます。 – stirringhalo

3

あなたがcharである(hex2digに引数を渡しています*)からcheckdigit(charが必要です)。実際にレジスタに文字をロードし、そのレジスタをスタックにプッシュして、charを渡す必要がありますcheckdigit

+0

ええ、そうです。それは私がやっているようにもできないことです.4バイトの文字列を個々の文字に分解してください。私は試しました:mov EDX、EBX/EDX、00000000000000000000000011111111B /プッシュEDXを試して、1文字をマスクしてください。アセンブラコードでand命令を使用してセグメンテーションを行います。またシフトも試しました。 – stirringhalo

関連する問題