2012-03-10 31 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