写在ARM汇编语言功能,在特定位置插入一个字符串到另一个字符串 [英] writing a function in ARM assembly language which inserts a string into another string at a specific location

查看:388
本文介绍了写在ARM汇编语言功能,在特定位置插入一个字符串到另一个字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要通过我的课的教科书之一,我偶然发现了这个问题:

I was going through one of my class's textbooks and I stumbled upon this problem:

将在ARM汇编语言的函数,将在特定位置插入一个字符串到另一个字符串。的功能是:
      的char * csinsert(字符* S1,字符* S2,INT LOC);

Write a function in ARM assembly language which will insert a string into another string at a specific location. The function is: char * csinsert( char * s1, char * s2, int loc ) ;

该函数具有一个指针在a1至S1,一个指向在A2 S2,并且在A3在何处插入发生的整数。该功能在A1返回一个指向新的字符串。

The function has a pointer to s1 in a1, a pointer to s2 in a2, and an integer in a3 as to where the insertion takes place. The function returns a pointer in a1 to the new string.

您可以使用库函数的strlen()和malloc。
      strlen的具有作为输入指针a1中的字符串并返回a1中的长度。
      其中,输入A1是要求空间和输出A1字节大小是一个指向请求的空间的malloc将分配空间给新的字符串。
      记住寄存器A1-A4在函数调用不保留它们的值。

You can use the library functions strlen and malloc. strlen has as input the pointer to the string in a1 and returns the length in a1. malloc will allocate space for the new string where a1 on input is the size in bytes of the space requested and on output a1 is a pointer to the requested space. Remember the registers a1-a4 do not retain their values across function calls.

这是字符串插入我创建了C语言驱动程序:

This is the C language driver for the string insert I created:

 #include <stdio.h>

extern char * csinsert( char * s1, char * s2, int loc ) ;
int main( int argc, char * argv[] )
{
char * s1 = "String 1 are combined" ;
char * s2 = " and string 2 " ;
int loc = 8 ;
char * result ;

result = csinsert( s1, s2, loc ) ;
printf( "Result: %s\n", result ) ;
}

我的汇编语言code到目前为止是:

My assembly language code so far is:

        .global csinsert
csinsert:
        stmfd sp!, {v1-v6, lr} 
        mov v1, a1             
        bl strlen              
        add a1, a1, #1         
        mov v2, a1
        add a2, a2
        mov v3, a2
        add a3, a3           
        bl malloc             
        mov v3, #0             
loop:           
        ldrb v4, [v1], #1       
        subs v2, v2, #1
        add v4, v4, a2         
        strb v4, [a1], #1                
        bne loop
        ldmfd sp!, {v1-v6, pc} @std
 .end

我不认为我的code正常工作。当我把两者联系起来决赛,也没有给予回复的结果。为什么我的code不能正常插入的文本?我相信这个问题是在装配程序,是不是返回任何东西?

I don't think my code works properly. When I link the two finals, there is no result given back. Why does my code not insert the string properly? I believe the issue is in the assembly program, is it not returning anything?

谁能解释我的错误是什么?我不知道如何使用库函数的问题提示来。
谢谢!

Can anyone explain what my mistake is? I'm not sure how to use the library functions the question hints to. Thanks!

推荐答案

警告:我一直在做的ASM 40+,我看着手臂了一下,但没有用它。不过,我把手臂ABI文档。

Caveat: I've been doing asm for 40+, I've looked at arm a bit, but not used it. However, I pulled the arm ABI document.

随着问题指出,A1-A4是的的$ P $对面​​的电话,其中匹配ABI pserved。你救的的A1,但你没有的的保存的的A2或A3。

As the problem stated, a1-a4 are not preserved across a call, which matches the ABI. You saved your a1, but you did not save your a2 or a3.

的strlen [或任何其他功能]允许使用A1-A4为临时暂存器。因此,为了提高效率,我的猜测是,的strlen [或的malloc ]用A2-A4为划伤,[从你的观点]破坏一些寄存器的值。

strlen [or any other function] is permitted to use a1-a4 as scratch regs. So, for efficiency, my guess is that strlen [or malloc] is using a2-a4 as scratch and [from your perspective] corrupting some of the register values.

这是你到了时间循环:,A2可能是一个的假的旅程的: - )

By the time you get to loop:, a2 is probably a bogus journey :-)

更新

我开始清理汇编。风格是在10倍比ASM C.更重要的每个的ASM线应该有一个侧边栏评论。而在这里或那里添加一个空行。因为你没有张贴更新的code,我在的变化,后位猜,我意识到你只有约25%左右。另外,我开始把事情搞得一团糟。

I started to clean up your asm. Style is 10x more important in asm than C. Every asm line should have a sidebar comment. And add a blank line here or there. Because you didn't post your updated code, I had to guess at the changes and after a bit, I realized you only had about 25% or so. Plus, I started to mess things up.

我分裂问题分为三个部分:结果
- code用C结果
- 以C code和生成用C结果ARM伪code
- code在ASM

I split the problem into three parts:
- Code in C
- Take C code and generate arm pseudo code in C
- Code in asm

如果你看看在C code和伪code,你会发现,指令的任何滥用放在一边,你的逻辑是错误的(例如,你需要两个的strlen 的malloc前调用

If you take a look at the C code and pseudo code, you'll notice that any misuse of instructions aside, your logic was wrong (e.g. you needed two strlen calls before the malloc)

所以,这里是你的汇编清洗风格[没有多少新的code]。请注意,我可能会打破一些现有的逻辑,但我的版本可能对眼睛更容易。我用卡分离的东西,把一切都排队。这可以提供帮助。此外,意见显示的意图的或注意的指令或架构的限制。

So, here is your assembler cleaned for style [not much new code]. Notice that I may have broken some of your existing logic, but my version may be easier on the eyes. I used tabs to separate things and got everything to line up. That can help. Also, the comments show intent or note limitations of instructions or architecture.

.global csinsert
csinsert:

    stmfd   sp!,{v1-v6,lr}              // preserve caller registers

    // preserve our arguments across calls
    mov     v1,a1
    mov     v2,a2
    mov     v3,a3

    // get length of destination string
    mov     a1,v1                       // set dest addr as strlen arg
    bl      strlen                      // call strlen

    add     a1,a1,#1                    // increment length
    mov     v4,a1                       // save it

    add     v3,v3                       // src = src + src (what???)
    mov     v5,v2                       // save it

    add     v3,v3                       // double the offset (what???)

    bl      malloc                      // get heap memory

    mov     v4,#0                       // set index for loop

loop:
    ldrb    v7,[v1],#1
    subs    v2,v2,#1
    add     v7,v7,a2
    strb    v7,[a1],#1
    bne     loop

    ldmfd   sp!,{v1-v6,pc} @std         // restore caller registers

    .end

首先,你应该在原型实C:

At first, you should prototype in real C:

// csinsert_real -- real C code
char *
csinsert_real(char *s1,char *s2,int loc)
{
    int s1len;
    int s2len;
    char *bp;
    int chr;
    char *bf;

    s1len = strlen(s1);
    s2len = strlen(s2);

    bf = malloc(s1len + s2len + 1);
    bp = bf;

    // copy over s1 up to but not including the "insertion" point
    for (;  loc > 0;  --loc, ++s1, ++bp) {
        chr = *s1;
        if (chr == 0)
            break;
        *bp = chr;
    }

    // "insert" the s2 string
    for (chr = *s2++;  chr != 0;  chr = *s2++, ++bp)
        *bp = chr;

    // copy the remainder of s1 [if any]
    for (chr = *s1++;  chr != 0;  chr = *s1++, ++bp)
        *bp = chr;

    *bp = 0;

    return bf;
}

然后,您可以[直到你满意的手臂]原型C伪code:

Then, you can [until you're comfortable with arm], prototype in C "pseudocode":

// csinsert_pseudo -- pseudo arm code
char *
csinsert_pseudo()
{

    // save caller registers

    v1 = a1;
    v2 = a2;
    v3 = a3;

    a1 = v1;
    strlen();
    v4 = a1;

    a1 = v2;
    strlen();

    a1 = a1 + v4 + 1;

    malloc();
    v5 = a1;

    // NOTE: load/store may only use r0-r7
    // and a1 is r0
#if 0
    r0 = a1;
#endif
    r1 = v1;
    r2 = v2;

    // copy over s1 up to but not including the "insertion" point
loop1:
    if (v3 == 0) goto eloop1;
    r3 = *r1;
    if (r3 == 0) goto eloop1;
    *r0 = r3;
    ++r0;
    ++r1;
    --v3;
    goto loop1;
eloop1:

    // "insert" the s2 string
loop2:
    r3 = *r2;
    if (r3 == 0) goto eloop2;
    *r0 = r3;
    ++r0;
    ++r2;
    goto loop2;
eloop2:

    // copy the remainder of s1 [if any]
loop3:
    r3 = *r1;
    if (r3 == 0) goto eloop3;
    *r0 = r3;
    ++r0;
    ++r1;
    goto loop3;
eloop3:

    *r0 = 0;

    a1 = v5;

    // restore caller registers
}

这篇关于写在ARM汇编语言功能,在特定位置插入一个字符串到另一个字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆