【发布时间】:2016-03-16 18:03:26
【问题描述】:
我是组装新手,我也在尝试了解我可以使用的工具。我必须为一个微型 C 程序创建一个可调用的汇编函数。目标是让用户按十六进制值输入字母 - 因此 A 为 41。然后 C 将此十六进制值作为无符号字符传递给汇编函数。下面是C代码
extern char *printbin(unsigned char);
int main(void)
{
unsigned int x;
printf("enter the character's ascii value in hex: \n");
scanf("%x",&x);
printf("The binary format for character %c is %s\n",
x, printbin((unsigned char)x));
return 0;
}
我的理解是在堆栈上应该有一个值 41 存储在一个字节中,因为在 C 字符中实际上也只是数字。这个假设是否正确。任务是将输入转换为两个 4 位二进制数字的输出字符串,每个数字用空格分隔,所以 0100 0001 我的第一个问题是如何将寄存器中的字节拆分为 4 位或仅 1 或4?我为汇编文件设置了一个骨架
.text
.globl _printbin
_printbin:
pushl %ebp
movl %esp, %ebp
movl 4(%ebp), %ecx #store the char in ecx register
jmp end
donibble: #function to convert digit to binary
end:
movl %ebp, %esp
popl %ebp
ret
但是我不知道如何继续抓取一半的字节。当我对它进行“工作”时,我可以只用 %el 抓取一个字节,而不是 %ecx ,但我不知道有任何类型的寄存器可以抓取少于 1 个字节的任何内容。任何帮助或想法将不胜感激。
更新的汇编代码
.text
.globl _printbin
_printbin:
pushl %ebp
movl %esp, %ebp
movl 4(%ebp), %edx #grabs the hex byte
movl $0, %eax #sets $eax to 0
shrb $4,%dl
jmp donibble
L2:
incl %eax
# addl 0x20, %return string #add the space.
movl 4(%ebp), %edx
AND %dl, 0x0f
jmp donibble
L3:
jmp end
donibble:
#Takes %dl and gets string and adds string to return String
cmpb %dl, 0x0
je Zero
cmpb %dl, 0x1
je One
Zero:
#add 0000 to string
jmp donibbleEnd
One:
#add 0001 to string
donibbleEnd:
#to send back to printbin
cmpb $0, %eax
je L2
jmp L3
end:
movl $returnString, %eax
movl %ebp, %esp
popl %ebp
ret
.data
returnString:
.asciz "1001 1100\n"
.end
有没有办法按照上面这个更新的结构添加到我的 $returnString 中?显然 addl "0000", $returnString 根本不起作用:)
【问题讨论】:
-
没有。您将不得不像在 C 中那样做位shitfing 和掩码。
x >> 4和x & 0x0f得到两半。 -
你可以在装配时移动和遮罩吗?我只看到使用 addl 等命令而不是 + 号的基本数学
-
您使用适当的说明进行转换和遮罩 :) 我把它留给您作为练习。您还可以使用汇编器的运算符对常量进行移位和屏蔽,但这不适用于此处。
-
术语注释:它们是指令,而不是“命令”。班次:查看
shl和shr指令。口罩:你有and、or、xor、not。 -
感谢最后两个 cmets。我会尝试看看我能从这里完成什么。我应该能够屏蔽和移动这些位以将它们分开。我将把那个数字转换成二进制字符串。