传递参数C - > NASM - > C

时间:2012-03-10 18:27:34

标签: c assembly nasm

不可否认,这是一些功课帮助,但我似乎无法解决一个具体问题。

我正在尝试编写一个带有十六进制字符串的程序,调用一个汇编程序函数,它给出了十六进制字符串的十进制值。该汇编程序函数在C中调用“checker”函数,该函数确保每个字符都是合法的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

2 个答案:

答案 0 :(得分:3)

您将参数传递给hex2dig(这是一个char *)到checkdigit(需要一个char)。您需要实际将一个字符加载到寄存器中,然后将该寄存器推送到堆栈以将char传递给checkdigit

答案 1 :(得分:1)

Chris Dodd是正确的 - 发送一个字符(8位字节)而不是指针(32位数量)。

到目前为止,除了清除它之外,你似乎没有对EDX做任何事情。此外,在从堆栈加载其值之前,您不需要将EBX清除为0(与写入“a = 12; a = 65;”相同 - 第一个赋值是无关紧要的,因为它会立即丢弃)。

无论如何,所以你已经将指向字符串的指针加载到EBX中。现在加载EBX指向的8位字节。其语法是[EBX],因此:

mov EDX, [EBX]

但这样做会加载4个字节(因为EDX是32位寄存器)。您只需要第一个字节,因此请指定EDX(DL)低8位的目标寄存器:

mov DL, [EBX]

你已经将EDX清除为0是一件好事(因为上面的指令只会覆盖底部的8位)。此时,EDX包含您要处理的字节,因此在堆栈上而不是EBX上推送EDX。

我希望这扩展了您对x86程序集的一般理解。