Passing Arguments C & # 8594; NASM & # 8594; C
This is admittedly some homemade help, but a specific issue that I can't get through.
I am trying to write a program that takes a string of hexadecimal characters, calls an assembler function that gives me the decimal value of the hexadecimal string. This assembler function calls the "checker" function in C, which ensures that each character is a valid HEX value.
My question is how to take the EBX register in assembly and correctly pass it to the C function expecting a character. I can't seem to move from assembler to C. Am I accidentally passing a pointer here? I also can't seem like my life can get an individual character out of EBX, even breaking it down into bytes.
Note. -1 when the character is invalid.
What I hope for:
Please enter the maximum four-digit hexadecimal integer using the hexadecimal string: FBE You are logged in: FBE FBE - F - 15
What I get: Enter the maximum four-digit hexadecimal integer using the hexadecimal string: FBE You are logged in: FBE FBE - M - -1
EDIT: The check digit function, as intended, should only accept single characters. So I will split the string in the main NASM function for full functionality. Still trying to get it to work with the character one time at a time.
FROM
#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 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
source to share
Chris Dodd is right - send a char (8-bit byte) instead of a pointer (32-bit amount).
So far, you don't seem to be doing anything with EDX other than cleaning. Also, you don't need to clear EBX to 0 before loading its value from the stack (same as writing "a = 12; a = 65;" - the first assignment is irrelevant, because it is discarded immediately).
Either way, you've loaded a pointer to a string into EBX. Now load the 8-bit byte pointed to by EBX. The syntax for this is [EBX], as such:
mov EDX, [EBX]
But this will load 4 bytes (because EDX is a 32-bit register). You only need the first byte, so specify the EDX (DL) low 8 bit target register:
mov DL, [EBX]
It's good that you've already cleared the EDX to 0 (because the above instruction only overwrites the bottom 8 bits). At this point, EDX contains the byte you want to process, so push EDX onto the stack instead of EBX.
I hope this has expanded your general understanding of x86 assembly.
source to share