如何使用ArmV8汇编语言将十进制转换为二进制示例:输入:43输出:101011
我主要不知道如何进行从十进制到二进制的转换
或如何将其从任何编程语言转换为ARMv8
这就是我所拥有的
ARMv8汇编语言代码
.data
decimal: .asciz "%s"
binary: .asciz "%d"
newline: .asciz "\n"
string_input_buffer: .space 256
userPrompt: .asciz "Input an integer: \n"
.text
.global main
main:
# Load the input prompt and print it out
ldr x0, =userPrompt
bl printf
# Take in the input and save it in the buffer
ldr x0, =decimal
ldr x1, =string_input_buffer
bl scanf
bl decToBin
done:
mov x0, #0
mov x8,#93
svc #0
decToBin:
// Convert Decimal to Binary
这是我在Java中拥有的代码
while(decimal != 0)
{
a = decimal%2;
b += a* Math.pow(10, count);
count++;
decimal = decimal/2;
}
我似乎无法理解如何将其翻译为手臂
答案 0 :(得分:1)
由于您正在编写汇编程序,因此我假设您已经了解数字已经以二进制格式存储在内存和寄存器中,并且操纵该数字的每个操作也是二进制操作。
您执行的Java代码正在创建一个整数,该整数与其无符号二进制表示形式的位数完全相同,而数字当然具有不同的值,因此其本身也具有不同的二进制表示形式。我发现很难想像除了打印出来的整数外,您还能用这个产生的整数做什么,但是在Java中已经有内置的函数了: Print an integer in binary format in Java
实际上,此功能的第一步是将每个数字转换为相应的字符,以便照原样打印。对于您构造的整数,也将遵循相同的过程以进行打印。因此,创建这样的整数对我来说似乎是多余的。所以问题是:“这真的是您想要做的吗?”
答案 1 :(得分:0)
如果您是因为某人的问题而问这个问题,那么您的目标应该是花费必要的时间来建立自己的,可行的解决方案:按照我的拙见,这是最好的学习方法。 / p>
这比使用qemu-system-aarch64
,aarch64-elf-as
,aarch64-elf-ld
和aarch64-elf-gdb
逐步组装,链接和调试aarch64程序容易。
这可以在Linux和Windows上完成-我使用的是Windows环境。
该工具链是从here下载的,而qemu-system-aarch64
是从here下载的。
如果您对基数/基数转换不满意,请首先在Internet上查找教程,例如this one。只有这样,您才应该开始寻找解决问题的方法。
当它专门用来详细解释aarch63指令集时,“探索工具”中的documention ARM is providing绝对是最好的恕我直言。
您的问题可以分为两部分:
以下示例对输入不执行任何验证,通常应执行以下操作:
/* ----------------------------------------------------
* A minimalist section of code for converting a
* zero-terminated string representating a decimal
* number into a zero-terminated string representating
* a binary number.
* --------------------------------------------------*/
.title "dec2bin.s"
.arch armv8-a
.text
.section .text.startup,"ax"
.globl Reset_Handler
Reset_Handler: ldr x0, =decimalsz // load address of decimalsz into x0.
mov x2, xzr // use x2 for computing the binary value - initial value is zero.
decascii2bin: ldrb w1, [x0], #1 // load byte pointed by x0, then increment x0 by 1.
cbz x1, bin2binascii // if x1 does contain zero, we reached the end of the input buffer.
sub w1, w1, #'0' // x1 does contain the ASCII value for character '4' or '3' - substracting ASCII value for '0'.
// we need to multiply the previous result by 10, then add the current digit:
add x3, xzr, x2, lsl #3 // x3 = 0 + x2 << 3, i.e. 8 * x2
add x2, x3, x2, lsl #1 // x2 = x3 + x2 < 1, i.e. 8 * x2 + 2 * x2 = 10 *x2
add x2, x2, x1 // if we are processing '4', x2 = x2 (0) * 10 + 4 = 4. if we are processing '43, x2 = x2 (40) * 10 + 3 = 43.
bl decascii2bin
bin2binascii: // x2 does now contain 43.
ldr x0, =binarysz // load address of binarysz into x0.
add x0, x0, #64 // x0 points to the byte which would contain the zero-termination if 32 bits were to be displayed.
clz x1, x2 // retrieve the number of bits set to zero for the number contained in x2.
sub x0, x0, x1 // number 43 begins with 58 zero bits, therefore we will only display 64 - 58 = 6 bits.
strb wzr, [x0], #-1 // store zero at binarysz + 6.
movk x3, #'0' // store '0' in x3.
nextbit: bfxil x3, x2, #0, #1 // extract 1 from x2 starting from most significant bit 0, and insert at low end of x3, leaving other bits unchanged.
strb w3, [x0], #-1 // store '0' or '1' to the byte location pointed by x0, then decrement x0 by one.
lsr x2, x2, #1 // shift x2 to the right by one bit.
add x1, x1, #1 // increment number of leading zero bits + number of bits processed, 58 + 1 at first pass, up to 64.
cmp x1, #64 // we are done of 64 bits were leading zero bits or processed.
b.ne nextbit
done: b.al done
.balign 16
// maximum possible value for un unsigned uint_64_t in decimal is:
// 18446744073709551615.
decimalsz: .asciz "43"
// maximum possible value for un unsigned uint_64_t in binary is:
// 1111111111111111111111111111111111111111111111111111111111111111.
// we need at most 65 bytes for 64 digits and a \0.
binarysz: .asciz "0000000000000000000000000000000000000000000000000000000000000000"
.end
组装/链接示例:
aarch64-elf-as -g -adhln -o dec2bin.o dec2bin.s > dec2bin.lst
aarch64-elf-ld -gc-sections -g -e Reset_Handler -Ttext-segment=0x42000000 -Map=dec2bin.map -o dec2bin.elf dec2bin.o
开始qemu:
qemu-system-aarch64 -m 256M -semihosting -machine virt,gic-version=2,secure=on,virtualization=on -S -gdb tcp::1234,ipv4 -monitor telnet:127.0.0.1:1235,server,nowait -cpu cortex-a53 -nographic -kernel dec2bin.elf
启动GDB(在另一个Windows控制台/ Linux shell中):
aarch64-elf-gdb dec2bin.elf
GNU gdb (GDB) 8.2
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-w64-mingw32 --target=aarch64-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from src\dec2bin\dec2bin.elf...done.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
Reset_Handler () at dec2bin.s:13
13 ldr x0, =decimalsz // load address of decimalsz into x0.
您现在可以逐步执行程序,并使用stepi
,p/x {$x0, $x1, $x2, $x3}
和x/s binarysz
命令检查寄存器和输出缓冲区。
完成时:您可以检查结果,然后退出GDB:
35 done: b.al done
(gdb) p/x {$x0, $x1, $x2, $x3}
$9 = {0x42000062, 0x40, 0x0, 0x31}
(gdb) x/s binarysz
0x42000063 <binarysz>: "101011"
(gdb) kill
Kill the program being debugged? (y or n) y
[Inferior 1 (Remote target) killed]
(gdb) quit