不可否认,这是一些功课帮助,但我似乎无法解决一个具体问题。
我正在尝试编写一个带有十六进制字符串的程序,调用一个汇编程序函数,它给出了十六进制字符串的十进制值。该汇编程序函数在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
答案 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程序集的一般理解。