NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: nasmnoob on March 10, 2012, 04:59:31 PM
-
Hey all, admittedly this is some homework help.
I'm trying to write a program which takes a string in of hex characters, calls an assembler function which gives me the decimal value of the hex string. That assembler function calls a "checker" function in C which makes sure each character is a legal HEX value.
My question is, how do I take an EBX register in assembler and properly pass it to a C function expecting a character. I can't seem to properly pass from assembler back to C. Am I accidentally passing a pointer here? I also can't seem for the life of me to get an individual character out of EBX:
#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;
}
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, [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
-
If you were to change your checkdigit function to accommodate the fact that you did pass a reference to a C string, without assuming that it has a fixed/predetermined size, how would you do so?
-
Besides the issue Keith mentions, one obvious error jumps out at me:
mov EBX, [EBP+8] ; copy the string to EDX
push EBX
call printf ; print whole string
Printf expects the address of a format string as its "first" (last pushed) parameter. Using the string that you passed into this function for that purpose isn't likely to produce useful results. Providing an appropriate format string here may give you a better idea what's going on in your function.
I'll try to look at this further, later.
Best,
Frank
-
Printf expects the address of a format string as its "first" (last pushed) parameter.
This will only cause an issue if you happen to have a format (%) code, as that equates to printf looking for more data on the stack in this case. So it is a potential source of "random" bugs.
However, Frank's illustration does suggest that, for safety/stability reasons, when using printf to print potentially random/variable string data, you should use "%s" and then supply the desired string to print.
A more direct way to address this issue is to use puts instead of printf.
-
A more direct way to address this issue is to use puts instead of printf.
Also note that puts will automatically append a newline, so you will not need to use "\n" within the string.
-
If you were to change your checkdigit function to accommodate the fact that you did pass a reference to a C string, without assuming that it has a fixed/predetermined size, how would you do so?
Unfortunately I cannot do that, the checkdigit function must according to the assignment only check individual characters.
Printf expects the address of a format string as its "first" (last pushed) parameter.
This will only cause an issue if you happen to have a format (%) code, as that equates to printf looking for more data on the stack in this case. So it is a potential source of "random" bugs.
However, Frank's illustration does suggest that, for safety/stability reasons, when using printf to print potentially random/variable string data, you should use "%s" and then supply the desired string to print.
A more direct way to address this issue is to use puts instead of printf.
I will definitely try puts and see if I can get a little further.
Thanks guys! I didn't realize no emails would show up in my inbox mentioning replies..
-
Click the "notify" option, and you "should" get email notification of any replies posted. (but it's an imperfect world!)
If your "checkdigit" function is expected to check only one character at a time, then that's what you've got to pass to it - you're just passing the address of the string back. When "checkdigit" returns, it has done the character-to-number conversion for you, and eax contains the number. Multiply a "result so far" (starting at zero) by 16 and add in the number you've got. Put the "result so far" in eax to return the decimal value.
I've got it "kinda working", but the display is a mess. Needs more work. Note that your "checkdigit" accepts only uppercase 'A' - 'F'... Is that okay, or do you need to "fix" it?
Best,
Frank