Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在ARM中打印浮点(VFP)数字?_Assembly_Printing_Floating Point_Arm - Fatal编程技术网

Assembly 如何在ARM中打印浮点(VFP)数字?

Assembly 如何在ARM中打印浮点(VFP)数字?,assembly,printing,floating-point,arm,Assembly,Printing,Floating Point,Arm,我需要在屏幕上打印一个浮点(VFP)数字来分配任务。我已经得到了prints和fgets函数来处理标准输入和输出,但这只适用于整数或字符串。我的教授要求我使用ARMSim来调试这个课程,所以我只限于使用ARMv5(不要问为什么,因为我不知道)。我对arm语言了解不多,请记住这一点 以下是我的代码,其中包含一个简单的main: .global prints, fprints, fgets @ PROGRAM .text .global main main: ldr r0, =euler

我需要在屏幕上打印一个浮点(VFP)数字来分配任务。我已经得到了prints和fgets函数来处理标准输入和输出,但这只适用于整数或字符串。我的教授要求我使用ARMSim来调试这个课程,所以我只限于使用ARMv5(不要问为什么,因为我不知道)。我对arm语言了解不多,请记住这一点

以下是我的代码,其中包含一个简单的main:

.global prints, fprints, fgets


@ PROGRAM
.text
.global main
main:
    ldr r0, =euler    
    vldr s0, [r0]        @load 2.718 into s0
    vmov.f32 r0, s0      @result is moved to r0 so as to turn it to string
    ldr r1, adr_str      @enough space is saved up to store the transformation to string result
    bl itoa
    bl prints               
    b exit

@Memory data adress in DATOS

adr_num: .word number       @Here the space for an int is defined (see end of document, section .DATA)
adr_str: .word string           @Here the space for a string is defined (see end of document, section .DATA)

@reading of the first character (n):
ldr r0, adr_num                     @where n will be stored
mov r1, #4                          @buffer for the first number
mov r2, #0                          @indicates fgets must read from stdin
bl fgets
bl atoi                             @turns to int so as to evaluate without caring about a "\n"
mov r5, r0                          @store de recived int

mov r0, r5                          @move result to register r0 so as to turn int to string
ldr r1, adr_str                     @enough space is saved so as to store the result of transformation
bl itoa
bl prints

b exit

exit:
mov r0, #0x18
mov r1, #0
swi 0x123456

@ prints: Returns an ASCII string ending in null to stdout
@
@ Abstract use:
@    prints(r0)
@ Inputs:
@    r0: memory adress to ASCII string ending in null
@ Resultado:
@    N/A, but string is writen to stdout (console)
prints:
    stmfd   sp!, {r0,r1,lr}
    ldr r1, =operands
    str r0, [r1,#4]
    bl  strlen
    str r0, [r1,#8]
    mov r0, #0x0
    str r0, [r1]
    mov r0, #0x05
    swi 0x123456
    ldmfd   sp!, {r0,r1,pc}



@ fgets: read a line of ASCII text from a stream of inputs (open text file or stdin)
@
@ Abstract use:
@    r0 = fgets(r0, r1, r2)
@ Inputs:
@    r0: memory adress of a buffer where first line will be stored
@    r1: buffer size (must acomodate an ending character)
@    r2: name of a file to open for input or "0" to read from stdin
@ Resultado:
@    r0: buffer memory adress if characters where able to be read or = if    @        characters wheren't read by an EOF error.
@        One text line including a terminating linefeed character
@        is read into the buffer, if the buffer is large enough.
@        Otherwise the buffer holds size-1 characters and a null byte.
@        Note: the line stored in the buffer will have only a linefeed
@        (\n) line ending, even if the input source has a DOS line
@        ending (a \r\n pair).
fgets:  stmfd   sp!, {r1-r4,lr}
    ldr r3, =operands
    str r2, [r3]    @ specify input stream
    mov r2, r0
    mov r4, r1
    mov r0, #1
    str r0, [r3,#8] @ to read one character
    mov r1, r3
    mov r3, r2
1:  subs    r4, r4, #1
    ble 3f      @ jump if buffer has been filled
    str r3, [r1,#4]
2:  mov r0, #0x06   @ read operation
    swi 0x123456
    cmp r0, #0
    bne 4f      @ branch if read failed
    ldrb    r0, [r3]
    cmp r0, #'\r'   @ ignore \r char (result is a Unix line)
    beq 2b
    add r3, r3, #1
    cmp r0, #'\n'
    bne 1b
3:  mov r0, #0
    strb    r0, [r3]
    mov r0, r2      @ set success result
    ldmfd   sp!, {r1-r4,pc}
4:  cmp r4, r2
    bne 3b      @ some chars were read, so return them
    mov r0, #0      @ set failure code
    strb    r0, [r2]    @ put empty string in the buffer
    ldmfd   sp!, {r1-r4,pc}

@ strlen: computes the lenght of a string made form ASCII characters ending in null
@
@ Abstract use:
@    r0 = strlen(r0)
@ Inputs:
@    r0: memory adress of an ASCII string enfing in null.
@ Resultado:
@    r0: string lenght (excluding ending byte)
strlen:
    stmfd   sp!, {r1-r3,lr}
    mov r1, #0
    mov r3, r0
1:  ldrb    r2, [r3], #1
    cmp r2, #0
    bne 1b
    sub r0, r3, r0
    ldmfd   sp!, {r1-r3,pc}


@ atoi: turns an ASCII string ending in null to it's int equivalent
@
@ Abstract use:
@    r0 = atoi(r0)
@ Inputs:
@    r0: memory adress of an ASCII string ending in null.
@ Resultado:
@    r0: value of te converted int
atoi:
    stmfd   sp!, {r1-r4,lr}
    mov r2, #0      @ holds result
    mov r3, #0      @ set to 1 if a negative number
    mov r4, #10
1:  ldrb    r1, [r0], #1    @ get next char
    cmp r1, #0
    beq 4f
    cmp r1, #' '
    beq 1b
    cmp r1, #'\n' @se añadio la regla para que no procese los '\n'
    beq 1b
    cmp r1, #'-'
    moveq   r3, #1
    ldreqb  r1, [r0], #1
    b   3f
2:  cmp r1, #9
    bgt 4f
    mul r2, r4, r2
    add r2, r2, r1
    ldrb    r1, [r0], #1
3:  subs    r1, r1, #'0'
    bge 2b
4:  cmp r3, #0
    moveq   r0, r2
    mvnne   r0, r2
    ldmfd   sp!, {r1-r4,pc}


    @ itoa: int to ASCII
    @
    @ Abstract use:
    @    r0 = itoa(r0, r1)
    @ Exit parameters:
    @    r0: signed integer
    @    r1: buffer adress that is large enough to keep the functions result,   @   @    which will be an ASCII string ending in NULL characterla direccion   @   @    de un buffer suficientemente grande para mantener el
    @ Resultado:
    @    r0: buffers adress
    itoa:
        stmfd   sp!, {r1-r7,lr}
        mov r7, r1      @ remember buffer address
        cmp r0, #0      @ check if negative and if zero
        movlt   r2, #'-'
        moveq   r2, #'0'
        strleb  r2, [r1],#1 @ store a '-' symbol or a '0' digit
        beq 3f
        mvnlt   r0, r0
        ldr r3, =4f     @ R3: multiple pointer
        mov r6, #0      @ R6: write zero digits? (no, for leading zeros)
    1:  ldr r4, [r3],#4 @ R4: current power of ten
        cmp r4, #1      @ stop when power of ten < 1
        blt 3f
        mov r5, #0      @ R5: multiples count
    2:  subs    r0, r0, r4  @ subtract multiple from value
        addpl   r5, r5, #1  @ increment the multiples count
        bpl 2b
        add r0, r0, r4  @ correct overshoot
        cmp r5, #0      @ if digit is '0' and ...
        cmpeq   r6, #0      @    if it's a leading zero
        beq 1b      @ then skip it
        mov r6, #1
        add r2, r5, #'0'    @ ASCII code for the digit
        strb    r2, [r1],#1 @ store it
        b   1b
    3:  mov r0, #0
        strb    r0, [r1]
        mov r0, r7
        ldmfd   sp!, {r1-r7,pc}
    4:  .word   1000000000, 100000000, 10000000, 1000000
        .word   100000, 10000, 1000, 100, 10, 1, 0


@ DATOS
.data
euler: .float 2.718
operands: .word 0, 0, 0
string: .space 32                           @buffer for a 32 character string

number: .space 4                            @buffer for a number (n y then k) + ending character
list: .space 4000                           @buffer for a 1000 numbers max list (only 999 will be used as true max)
found: .ascii "NUmber is in the list."
space: .space 2
unfound: .ascii "Number is not on the list."    

。全局打印、FP打印、FGET
@节目
文本
.全球主要
主要内容:
ldr r0,=欧拉
vldr s0,[r0]@将2.718加载到s0中
vmov.f32 r0,s0@result被移动到r0,以便将其转换为字符串
ldr r1,adr_str@节省了足够的空间来存储转换为字符串的结果
基里托亚
bl印刷品
b出口
@DATOS中的内存数据地址
adr_num:.word number@此处定义了int的空格(请参见文档末尾的.DATA部分)
adr_str:.word string@此处定义了字符串的空格(请参见文档末尾的.DATA部分)
@读取第一个字符(n):
ldr r0,adr_num@其中n将被存储
mov r1,#4@第一个数字的缓冲区
mov r2,#0@表示FGET必须从stdin读取
bl fgets
bl atoi@变为int,以便在不考虑“\n”的情况下进行计算
mov r5,r0@存储接收int
mov r0,r5@将结果移动到寄存器r0,以便将int转换为字符串
ldr r1,adr_str@节省了足够的空间以存储转换结果
基里托亚
bl印刷品
b出口
出口:
mov r0,#0x18
移动r1,#0
swi 0x123456
@打印:将以null结尾的ASCII字符串返回到标准输出
@
@摘要用途:
@印刷品(r0)
@投入:
@r0:以null结尾的ASCII字符串的内存地址
@结果:
@不适用,但字符串已写入标准输出(控制台)
印刷品:
stmfd sp!,{r0,r1,lr}
ldr r1,=操作数
str r0[r1,#4]
bl斯特伦
str r0[r1,#8]
mov r0,#0x0
strr0[r1]
mov r0,#0x05
swi 0x123456
ldmfd sp!,{r0,r1,pc}
@fgets:从输入流中读取一行ASCII文本(打开文本文件或标准文本)
@
@摘要用途:
@r0=fgets(r0,r1,r2)
@投入:
@r0:将存储第一行的缓冲区的内存地址
@r1:缓冲区大小(必须包含结束字符)
@r2:要打开以进行输入的文件名或要从stdin读取的“0”
@结果:
@r0:缓冲区内存地址如果字符可以读取,或=如果@字符不能被EOF错误读取。
@一个文本行,包括终止换行符
@如果缓冲区足够大,则读取到缓冲区中。
@否则,缓冲区将保存大小为1的字符和空字节。
@注意:缓冲区中存储的行只有换行符
@(\n)行结束,即使输入源有DOS行
@正在结束(一对\r\n)。
fgets:stmfd sp!,{r1-r4,lr}
ldr r3,=操作数
str r2,[r3]@指定输入流
mov r2,r0
mov r4,r1
mov r0,#1
str r0,[r3,#8]@读取一个字符
mov r1,r3
mov r3,r2
1:潜艇r4,r4,#1
ble 3f@缓冲区已满时跳转
str r3[r1,#4]
2:mov r0,#0x06@读取操作
swi 0x123456
cmp r0,#0
bne 4f@branch如果读取失败
ldrb r0,[r3]
cmp r0,#'\r'@ignore\r char(结果是Unix行)
贝基2b
加上r3,r3,#1
cmp r0,#'\n'
bne 1b
3:mov r0,#0
strb r0,[r3]
mov r0,r2@设置成功结果
ldmfd sp!,{r1-r4,pc}
4:cmp r4,r2
bne 3b@读取了一些字符,请返回它们
mov r0,#0@设置故障代码
strb r0,[r2]@将空字符串放入缓冲区
ldmfd sp!,{r1-r4,pc}
@strlen:计算由以null结尾的ASCII字符组成的字符串的长度
@
@摘要用途:
@r0=strlen(r0)
@投入:
@r0:ASCII字符串的内存地址为null。
@结果:
@r0:字符串长度(不包括结束字节)
斯特伦:
stmfd sp!,{r1-r3,lr}
移动r1,#0
mov r3,r0
1:ldrb r2,[r3],#1
cmp r2,#0
bne 1b
子r0、r3、r0
ldmfd sp!,{r1-r3,pc}
@atoi:将以null结尾的ASCII字符串转换为它的int等效值
@
@摘要用途:
@r0=atoi(r0)
@投入:
@r0:以null结尾的ASCII字符串的内存地址。
@结果:
@r0:te转换的int值
原子能机构:
stmfd sp!,{r1-r4,lr}
mov r2,#0@保留结果
mov r3,如果为负数,则#0@设置为1
mov r4,#10
1:ldrbr1[r0],#1@get next char
cmp r1,#0
BEQ4F
cmp r1,#“
贝基1b
cmp r1,'\n'@se añadio la regla para que no procese los'\n'
贝基1b
cmp r1,#'-'
移动q r3,#1
ldreqb r1,[r0],#1
b 3f
2:cmp r1#9
bgt4f
mul r2,r4,r2
加上r2,r2,r1
ldrb r1,[r0],#1
3:接头r1、r1、#“0”
bge2b
4:cmp r3,#0
移动q r0,r2
mvnne r0,r2
ldmfd sp!,{r1-r4,pc}
@itoa:int到ASCII
@
@摘要用途:
@r0=itoa(r0,r1)
@退出参数:
@r0:有符号整数
@r1:足够大的缓冲区地址,以保留函数结果,@@这将是一个以空字符“direccion”结尾的ASCII字符串@@de un buffer suficiente grande para mantener el
@结果:
@r0:缓冲区地址
itoa:
stmfd sp!,{r1-r7,lr}
mov r7,r1@记住缓冲区地址
cmp r0,#0@检查是否为负,如果为零
移动r2,#'-'
移动r2,#“0”
strleb r2、[r1]、#1@存储一个“-”符号或一个“0”数字
beq 3f
mvnlt r0,r0
ldr r3,=4f@r3:多指针
mov r6,#0@r6:写入零位?(否,用于前导零)
1:ldr r4,[r3],#4@r4:当前功率
main:
    ldr r0, =euler              @en .data esta el valor euler
    vldr s0, [r0]               @cargo euler = S0

    vcvt.u32.f32 s1, s0         @convierto euler a entero = S1
    vmov.f32 r0, s1             @lo paso a R0 para imprimir
    ldr r1, adr_str             @*
    bl itoa                     @*
    bl prints                   @*
    ldr r0, =dot                @cargo el punto decimal que esta en punto data
    bl prints                   @*
    vcvt.f32.u32 s1, s1         @convierto la parte entera de euler de nuevo a flotante S1
    vsub.f32 s2, s0, s1         @le quito la parte entera a euler = S2
    ldr r0, =decExp             @en .data esta el valor decExp
    vldr s3, [r0]               @cargo 100 para obtener los decimales 
    vmul.f32 s2, s2, s3         @multiplico los decimales por 1000 = S2
    vcvt.u32.f32 s3, s2         @transformo los "decimales" a entero = S3
    vmov.f32 r0, s3             @lo muevo a R0 para imprimir
    ldr r1, adr_str             @*
    bl itoa                     @*
    bl prints                   @*
    b exit                      @*