2012-03-10 29 views
3

不可否認,這是一些家庭作業的幫助,但一個具體的問題,我似乎無法通過。傳遞參數C - > NASM - > C

我想寫一個程序,它需要一個字符串的十六進制字符,調用一個彙編函數,它給了我十六進制字符串的十進制值。該彙編程序函數在C中調用「檢查器」函數,以確保每個字符都是合法的HEX值。

我的問題是,我如何在彙編程序中使用EBX寄存器並將其正確地傳遞給C函數,期望字符。我似乎無法正確地從彙編程序返回到C.我是不小心在這裏傳遞了一個指針?即使將其分解爲字節,我也無法像從EBX中獲取單個字符一樣。

注意,當字符無效時返回-1。

什麼我希望的:

請使用十六進制數字的字符串輸入一個最大的4位十六進制整數:FBE 您輸入:FBE FBE - F - 15

我能得到什麼: 請輸入使用的十六進制數字的字符串最大4位十六進制整數:FBE 您輸入:FBE FBE - M - -1

編輯:根據分配必須只需要單個字符的校驗位功能。所以我將分解主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是正確的 - 發送字符(8位字節)而不是指針(32位字節)位數量)。

到目前爲止,除了清除它之外,您似乎沒有對EDX做任何事情。此外,在從堆棧中加載其值之前,您不需要將EBX清除爲0(與寫入「a = 12; a = 65;」相同 - 第一個分配不相關,因爲它立即被丟棄)。

無論如何,所以您已經將一個指向字符串的指針加載到EBX中。現在加載EBX指向的8位字節。對此的句法是[EBX],因爲這樣的:

mov EDX, [EBX] 

但這樣做將加載4個字節(因爲EDX是一個32位寄存器)。你只需要第一個字節,所以指定EDX的低8位的目標寄存器(DL):

mov DL, [EBX] 

這是你已經開通EDX 0的好東西(因爲上面的指令只覆蓋底部8位)。此時,EDX包含您想要處理的字節,因此將EDX壓入堆棧而不是EBX。

我希望這擴大了您對x86彙編的一般理解。

+0

謝謝!道歉一點代碼cruft。我真的不確定是否傳遞了一個指針或值(像我想的那樣)。這很好解釋。是的,當我編程時間過長時,它有助於揭開一些神祕的東西。 – stirringhalo 2012-03-11 21:49:33

3

你傳遞的參數hex2dig(這是一個char *)到checkdigit(它期望一個字符)。你需要實際加載一個字符到一個寄存器,然後將該寄存器推入堆棧以傳遞一個字符到checkdigit

+0

嗯,是的。這是我甚至無法做到的事情,將4字節的字符串分解爲單個字符。我試過:mov EDX,EBX /和EDX,00000000000000000000000011111111B /推EDX試圖屏蔽一個字符。它使用和指令在彙編代碼中進行段錯誤。也嘗試過輪班。 – stirringhalo 2012-03-11 04:06:54