我是装配新手,我也在努力了解我所掌握的工具。我必须为一个小C程序创建一个可调用的汇编函数。目标是让用户输入字母十六进制值-so 41表示A.然后C将此十六进制值作为unsigned char传递给汇编函数。以下是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抓住一个字节来使它只有8位而不是%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根本不起作用:)
答案 0 :(得分:1)
这是该功能的一个奇怪的原型。你应该返回一个指向静态缓冲区的指针吗?更典型的设计是调用者将指针传递给缓冲区,函数可以存储该字符串。
通常的做法是利用移位指令将CF
设置为最后一位移出的事实。然后,您可以使用setc
获取零或一,并将其转换为ascii '0'
或'1'
。另一个技巧是adc $0
或adc $'0'
来读取进位标志。
复制寄存器并使用and
来获得低位也是可行的。
如果您遇到困难,请使用搜索功能。以前有过关于此的SO问题。尝试在x86和/或assembly标记内进行搜索。查看x86标签wiki,了解许多与初学者和参考资料的良好链接。
答案 1 :(得分:0)
要记录关闭这个。这是我结束的代码。我感谢大家的帮助。
.text
.globl _printbin
_printbin:
pushl %ebp
movl %esp, %ebp
movb 8(%ebp), %dl #grabs the hex byte
movl $0, %eax #sets $eax to 0
shrb $4, %dl
movl $returnString, %ecx
pushl %ebx #free up ebx
jmp donibble
returnFromDonibble:
incl %ecx
movb 8(%ebp), %dl
movb $0x0f, %al
andb $15, %dl
movb $0x39, %al
cmpb (%ecx), %al
je donibble
jne end
donibble:
#Takes %dl and gets string and adds string to return String
movb %dl, %bl
movb $0x08, %al
andb $8,%dl
je zero
jne one
one:
movb $0x31, (%ecx)
incl %ecx
jmp L2
zero:
movb $0x30, (%ecx)
incl %ecx
jmp L2
L2:
movb %bl, %dl
movb $0x04, %al
andb $4, %dl
je zero2
jne one2
one2:
movb $0x31, (%ecx)
incl %ecx
jmp L3
zero2:
movb $0x30, (%ecx)
incl %ecx
jmp L3
L3:
movb %bl, %dl
movb $0x02, %al
andb $2, %dl
je zero3
jne one3
one3:
movb $0x31, (%ecx)
incl %ecx
jmp L4
zero3:
movb $0x30, (%ecx)
incl %ecx
jmp L4
L4:
movb %bl, %dl
movb $0x01, %al
andb $1, %dl
je zero4
jne one4
one4:
movb $0x31, (%ecx)
incl %ecx
jmp returnFromDonibble
zero4:
movb $0x30, (%ecx)
inc %ecx
jmp returnFromDonibble
end:
popl %ebx
movl $returnString, %eax
movl %ebp, %esp
popl %ebp
ret
.data
returnString: .asciz "9999 9999"
.end