Передача аргументов C -> NASM -> C - PullRequest
3 голосов
/ 10 марта 2012

по общему признанию, это - некоторая домашняя помощь, но определенная проблема, которую я, кажется, не могу обойти.

Я пытаюсь написать программу, которая принимает строку из шестнадцатеричных символов, вызывает функцию ассемблеракоторый дает мне десятичное значение шестнадцатеричной строки.Эта ассемблерная функция вызывает функцию «проверки» в C, которая гарантирует, что каждый символ является допустимым значением HEX.

Мой вопрос: как мне взять регистр EBX в ассемблере и правильно передать его функции C, ожидающейхарактер.Кажется, я не могу правильно перейти от ассемблера обратно к C. Я случайно передал указатель здесь?Я также не могу себе представить, чтобы из меня получался отдельный символ из EBX, даже разбив его на байты.

Примечание: -1 возвращается, когда символ недопустим.

На что я надеюсь:

Пожалуйста, введите максимальное четырехзначное шестнадцатеричное целое число, используя строку шестнадцатеричных цифр: FBE Вы ввели: FBE FBE - F - 15

Что я получу: пожалуйставведите максимальное четырехзначное шестнадцатеричное целое, используя строку шестнадцатеричных цифр: 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 ]

3 голосов
/ 10 марта 2012

Вы передаете аргумент hex2dig (который является символом *) checkdigit (который ожидает символ).Вам нужно загрузить символ в регистр, а затем поместить этот регистр в стек, чтобы передать символ в checkdigit

1 голос
/ 11 марта 2012

Крис Додд прав: отправьте символ (8-битный байт) вместо указателя (32-битное количество).

Пока что вы, кажется, ничего не делаете с EDX, кроме как очищаете его. Кроме того, вам не нужно очищать EBX до 0 перед загрузкой его значения из стека (так же, как и запись «a = 12; a = 65;» - первое присваивание не имеет значения, потому что оно сразу выбрасывается).

В любом случае, вы загрузили указатель на строку в EBX. Теперь загрузите 8-битный байт, на который указывает EBX. Синтаксис для этого [EBX], как таковой:

mov EDX, [EBX]

Но при этом будет загружено 4 байта (потому что EDX - это 32-битный регистр). Вам нужен только первый байт, поэтому укажите целевой регистр младших 8 битов EDX (DL):

mov DL, [EBX]

Хорошо, что вы уже очистили EDX до 0 (потому что вышеприведенная инструкция перезаписывает только младшие 8 бит). На этом этапе EDX содержит байт, который вы хотите обработать, поэтому вставьте EDX в стек вместо EBX.

Надеюсь, это расширило ваше общее понимание сборки x86.

...