arm assembly junk only on strings of length 12











up vote
0
down vote

favorite












I encountered a strange problem while coding a linked list in arm assembly on the raspberry pi. my linked list works for all strings except strings with a length of 12. it displays a junk character at the end of all strings with a length of 12 and I cannot figure out why



any help is appreciated



here is the input function I'm using, it outputs the address to the malloc'd string in R0 and seems to function correctly for all strings not length 12:



.equ    BUFSIZE2,256

.data
inputbuf2: .ds BUFSIZE2
prompt: .asciz "Enter: "
p1: .word 0

input:
push {R1,R2,R5,R14}
mov R0,#0
bl v_ascz @ prints string in R1
ldr R1,=inputbuf2
mov R2,#BUFSIZE2
bl c_ascz @ does service call for input, returns in R1
bl v_ascz
bl v_nl
bl strlen @ returns string length of R1 into R0
sub R0,#1
mov R5,R0
bl alloc
bl store
ldr R0,=p1
ldr R0,[R0]
pop {R1,R2,R5,R14}
bx LR

alloc:
push {R0-R4,R14}
bl malloc
ldr R1,=p1
str R0,[R1]
pop {R0-R4,R14}
bx LR

store:
push {R1-R4,R14}
mov R2,#0 @ index
ldr R4,=p1
ldr R4,[R4]
loop: ldrb R3,[R1],#1
strb R3,[R4],#1
add R2,#1
cmp R2,R5
blt loop

mov R3,#0
strb R3,[R4] @ store null at end of string
pop {R1-R4,R14}
bx LR


.end


And here's the linked list add node function I'm using. It allocates 8 bytes and stores the address to the data in the first four and the address to the next node in the last 4:



.global list_add
@ R1 = addr of head
@ R2 = addr of tail
@ R3 = data
.data
node: .word 0

list_add:
push {R1-R4,R14}
bl alloc
push {R2}
ldr R2,[R2]
cmp R2,#0
pop {R2}
beq first_node
@ normal add
ldr R4,=node
ldr R4,[R4]
push {R2}
ldr R2,[R2] @ R2 = tail node
str R4,[R2,#4] @ R2 next ptr = node
pop {R2}
str R4,[R2] @ tail = node
str R3,[R4] @ node data = first addr of data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4,R14}
bx LR

first_node:
push {R1-R4}
ldr R4,=node
ldr R4,[R4]
str R4,[R1] @ head = node
str R4,[R2] @ tail = node
str R3,[R4] @ node data = data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4}
pop {R1-R4,R14}
bx LR

alloc:
push {R1-R3,R14}
mov R0,#8
bl malloc
ldr R1,=node
str R0,[R1]
ldr R1,[R1]
mov R3,#0
str R3,[R1]
str R3,[R1,#4]
pop {R1-R3,R14}
bx LR


Adding a bunch of random strings centered around my girlfriend's dog, wriggly, this is the output. ignore the numbers, they're the decimal addresses of the malloc'd memory










share|improve this question
























  • Use a debugger, check where the memory contents don't match what you assume them to be, go from there to figure out where the assumptions and code split - that's probably your bug. Going by the output alone, it seems your strings are not properly terminated.
    – domen
    Nov 22 at 8:21










  • Thank you I will keep trying! The strings are null terminated and it really only happens on strings specifically length 12, I’ve tested a lot of different sizes so that’s really what’s stumping me! I will continue digging though
    – frog spit
    Nov 22 at 13:57















up vote
0
down vote

favorite












I encountered a strange problem while coding a linked list in arm assembly on the raspberry pi. my linked list works for all strings except strings with a length of 12. it displays a junk character at the end of all strings with a length of 12 and I cannot figure out why



any help is appreciated



here is the input function I'm using, it outputs the address to the malloc'd string in R0 and seems to function correctly for all strings not length 12:



.equ    BUFSIZE2,256

.data
inputbuf2: .ds BUFSIZE2
prompt: .asciz "Enter: "
p1: .word 0

input:
push {R1,R2,R5,R14}
mov R0,#0
bl v_ascz @ prints string in R1
ldr R1,=inputbuf2
mov R2,#BUFSIZE2
bl c_ascz @ does service call for input, returns in R1
bl v_ascz
bl v_nl
bl strlen @ returns string length of R1 into R0
sub R0,#1
mov R5,R0
bl alloc
bl store
ldr R0,=p1
ldr R0,[R0]
pop {R1,R2,R5,R14}
bx LR

alloc:
push {R0-R4,R14}
bl malloc
ldr R1,=p1
str R0,[R1]
pop {R0-R4,R14}
bx LR

store:
push {R1-R4,R14}
mov R2,#0 @ index
ldr R4,=p1
ldr R4,[R4]
loop: ldrb R3,[R1],#1
strb R3,[R4],#1
add R2,#1
cmp R2,R5
blt loop

mov R3,#0
strb R3,[R4] @ store null at end of string
pop {R1-R4,R14}
bx LR


.end


And here's the linked list add node function I'm using. It allocates 8 bytes and stores the address to the data in the first four and the address to the next node in the last 4:



.global list_add
@ R1 = addr of head
@ R2 = addr of tail
@ R3 = data
.data
node: .word 0

list_add:
push {R1-R4,R14}
bl alloc
push {R2}
ldr R2,[R2]
cmp R2,#0
pop {R2}
beq first_node
@ normal add
ldr R4,=node
ldr R4,[R4]
push {R2}
ldr R2,[R2] @ R2 = tail node
str R4,[R2,#4] @ R2 next ptr = node
pop {R2}
str R4,[R2] @ tail = node
str R3,[R4] @ node data = first addr of data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4,R14}
bx LR

first_node:
push {R1-R4}
ldr R4,=node
ldr R4,[R4]
str R4,[R1] @ head = node
str R4,[R2] @ tail = node
str R3,[R4] @ node data = data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4}
pop {R1-R4,R14}
bx LR

alloc:
push {R1-R3,R14}
mov R0,#8
bl malloc
ldr R1,=node
str R0,[R1]
ldr R1,[R1]
mov R3,#0
str R3,[R1]
str R3,[R1,#4]
pop {R1-R3,R14}
bx LR


Adding a bunch of random strings centered around my girlfriend's dog, wriggly, this is the output. ignore the numbers, they're the decimal addresses of the malloc'd memory










share|improve this question
























  • Use a debugger, check where the memory contents don't match what you assume them to be, go from there to figure out where the assumptions and code split - that's probably your bug. Going by the output alone, it seems your strings are not properly terminated.
    – domen
    Nov 22 at 8:21










  • Thank you I will keep trying! The strings are null terminated and it really only happens on strings specifically length 12, I’ve tested a lot of different sizes so that’s really what’s stumping me! I will continue digging though
    – frog spit
    Nov 22 at 13:57













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I encountered a strange problem while coding a linked list in arm assembly on the raspberry pi. my linked list works for all strings except strings with a length of 12. it displays a junk character at the end of all strings with a length of 12 and I cannot figure out why



any help is appreciated



here is the input function I'm using, it outputs the address to the malloc'd string in R0 and seems to function correctly for all strings not length 12:



.equ    BUFSIZE2,256

.data
inputbuf2: .ds BUFSIZE2
prompt: .asciz "Enter: "
p1: .word 0

input:
push {R1,R2,R5,R14}
mov R0,#0
bl v_ascz @ prints string in R1
ldr R1,=inputbuf2
mov R2,#BUFSIZE2
bl c_ascz @ does service call for input, returns in R1
bl v_ascz
bl v_nl
bl strlen @ returns string length of R1 into R0
sub R0,#1
mov R5,R0
bl alloc
bl store
ldr R0,=p1
ldr R0,[R0]
pop {R1,R2,R5,R14}
bx LR

alloc:
push {R0-R4,R14}
bl malloc
ldr R1,=p1
str R0,[R1]
pop {R0-R4,R14}
bx LR

store:
push {R1-R4,R14}
mov R2,#0 @ index
ldr R4,=p1
ldr R4,[R4]
loop: ldrb R3,[R1],#1
strb R3,[R4],#1
add R2,#1
cmp R2,R5
blt loop

mov R3,#0
strb R3,[R4] @ store null at end of string
pop {R1-R4,R14}
bx LR


.end


And here's the linked list add node function I'm using. It allocates 8 bytes and stores the address to the data in the first four and the address to the next node in the last 4:



.global list_add
@ R1 = addr of head
@ R2 = addr of tail
@ R3 = data
.data
node: .word 0

list_add:
push {R1-R4,R14}
bl alloc
push {R2}
ldr R2,[R2]
cmp R2,#0
pop {R2}
beq first_node
@ normal add
ldr R4,=node
ldr R4,[R4]
push {R2}
ldr R2,[R2] @ R2 = tail node
str R4,[R2,#4] @ R2 next ptr = node
pop {R2}
str R4,[R2] @ tail = node
str R3,[R4] @ node data = first addr of data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4,R14}
bx LR

first_node:
push {R1-R4}
ldr R4,=node
ldr R4,[R4]
str R4,[R1] @ head = node
str R4,[R2] @ tail = node
str R3,[R4] @ node data = data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4}
pop {R1-R4,R14}
bx LR

alloc:
push {R1-R3,R14}
mov R0,#8
bl malloc
ldr R1,=node
str R0,[R1]
ldr R1,[R1]
mov R3,#0
str R3,[R1]
str R3,[R1,#4]
pop {R1-R3,R14}
bx LR


Adding a bunch of random strings centered around my girlfriend's dog, wriggly, this is the output. ignore the numbers, they're the decimal addresses of the malloc'd memory










share|improve this question















I encountered a strange problem while coding a linked list in arm assembly on the raspberry pi. my linked list works for all strings except strings with a length of 12. it displays a junk character at the end of all strings with a length of 12 and I cannot figure out why



any help is appreciated



here is the input function I'm using, it outputs the address to the malloc'd string in R0 and seems to function correctly for all strings not length 12:



.equ    BUFSIZE2,256

.data
inputbuf2: .ds BUFSIZE2
prompt: .asciz "Enter: "
p1: .word 0

input:
push {R1,R2,R5,R14}
mov R0,#0
bl v_ascz @ prints string in R1
ldr R1,=inputbuf2
mov R2,#BUFSIZE2
bl c_ascz @ does service call for input, returns in R1
bl v_ascz
bl v_nl
bl strlen @ returns string length of R1 into R0
sub R0,#1
mov R5,R0
bl alloc
bl store
ldr R0,=p1
ldr R0,[R0]
pop {R1,R2,R5,R14}
bx LR

alloc:
push {R0-R4,R14}
bl malloc
ldr R1,=p1
str R0,[R1]
pop {R0-R4,R14}
bx LR

store:
push {R1-R4,R14}
mov R2,#0 @ index
ldr R4,=p1
ldr R4,[R4]
loop: ldrb R3,[R1],#1
strb R3,[R4],#1
add R2,#1
cmp R2,R5
blt loop

mov R3,#0
strb R3,[R4] @ store null at end of string
pop {R1-R4,R14}
bx LR


.end


And here's the linked list add node function I'm using. It allocates 8 bytes and stores the address to the data in the first four and the address to the next node in the last 4:



.global list_add
@ R1 = addr of head
@ R2 = addr of tail
@ R3 = data
.data
node: .word 0

list_add:
push {R1-R4,R14}
bl alloc
push {R2}
ldr R2,[R2]
cmp R2,#0
pop {R2}
beq first_node
@ normal add
ldr R4,=node
ldr R4,[R4]
push {R2}
ldr R2,[R2] @ R2 = tail node
str R4,[R2,#4] @ R2 next ptr = node
pop {R2}
str R4,[R2] @ tail = node
str R3,[R4] @ node data = first addr of data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4,R14}
bx LR

first_node:
push {R1-R4}
ldr R4,=node
ldr R4,[R4]
str R4,[R1] @ head = node
str R4,[R2] @ tail = node
str R3,[R4] @ node data = data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4}
pop {R1-R4,R14}
bx LR

alloc:
push {R1-R3,R14}
mov R0,#8
bl malloc
ldr R1,=node
str R0,[R1]
ldr R1,[R1]
mov R3,#0
str R3,[R1]
str R3,[R1,#4]
pop {R1-R3,R14}
bx LR


Adding a bunch of random strings centered around my girlfriend's dog, wriggly, this is the output. ignore the numbers, they're the decimal addresses of the malloc'd memory







assembly raspberry-pi arm






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 6:21

























asked Nov 22 at 6:15









frog spit

32




32












  • Use a debugger, check where the memory contents don't match what you assume them to be, go from there to figure out where the assumptions and code split - that's probably your bug. Going by the output alone, it seems your strings are not properly terminated.
    – domen
    Nov 22 at 8:21










  • Thank you I will keep trying! The strings are null terminated and it really only happens on strings specifically length 12, I’ve tested a lot of different sizes so that’s really what’s stumping me! I will continue digging though
    – frog spit
    Nov 22 at 13:57


















  • Use a debugger, check where the memory contents don't match what you assume them to be, go from there to figure out where the assumptions and code split - that's probably your bug. Going by the output alone, it seems your strings are not properly terminated.
    – domen
    Nov 22 at 8:21










  • Thank you I will keep trying! The strings are null terminated and it really only happens on strings specifically length 12, I’ve tested a lot of different sizes so that’s really what’s stumping me! I will continue digging though
    – frog spit
    Nov 22 at 13:57
















Use a debugger, check where the memory contents don't match what you assume them to be, go from there to figure out where the assumptions and code split - that's probably your bug. Going by the output alone, it seems your strings are not properly terminated.
– domen
Nov 22 at 8:21




Use a debugger, check where the memory contents don't match what you assume them to be, go from there to figure out where the assumptions and code split - that's probably your bug. Going by the output alone, it seems your strings are not properly terminated.
– domen
Nov 22 at 8:21












Thank you I will keep trying! The strings are null terminated and it really only happens on strings specifically length 12, I’ve tested a lot of different sizes so that’s really what’s stumping me! I will continue digging though
– frog spit
Nov 22 at 13:57




Thank you I will keep trying! The strings are null terminated and it really only happens on strings specifically length 12, I’ve tested a lot of different sizes so that’s really what’s stumping me! I will continue digging though
– frog spit
Nov 22 at 13:57












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










Strings, by convention, are terminated by a zero byte called the 'termination character'.



When you call strlen you obtain the number of characters in the string, excluding the termination character that marks its end. This causes two problems:




  • When you loop to copy the string, you are not copying the termination character. Your string will therefore end at the next byte in memory that happens to be a zero, which could be anywhere. You're seeing the result of undefined behaviour: there's no reason why 12 characters should not work when other numbers do, it's just a consequence of your specific circumstances.

  • If you were to add the termination character, you'd be overflowing your destination string buffer, because your call to malloc also doesn't allocate enough space for the termination character.


While I'm here, I might as well also refer you to the ARM ABI, and specifically the part about the procedure call standard. While the ABI does not rule out using r0-r3 for intermediate values, these registers (along with r12) are 'call-clobbered' so it is typical to use r4-r11 for intermediate calculation. Functions must preserve r4-r11, usually by using the stack. Your use of r5 to hold a function argument (to store) is therefore contrary to the ABI, so your store function would not be callable from ABI-compliant code; and your pushing/popping of r1-r3 in several places is unnecessary if your callers also conform to the ABI. Also of note is that the ABI requires 8-byte stack alignment across function calls in different translation units, so it's a good idea to get into the habit of pushing and popping even numbers of registers to maintain this. (If you call a library function like malloc or strlen without ensuring 8-byte alignment, for example, you could run into undefined behaviour again.)






share|improve this answer





















  • Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
    – frog spit
    Nov 22 at 13:50












  • There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
    – cooperised
    Nov 22 at 15:45










  • I did but I don’t have enough posts or whatever for it to count, thank you though!
    – frog spit
    Nov 23 at 0:40











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53424896%2farm-assembly-junk-only-on-strings-of-length-12%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










Strings, by convention, are terminated by a zero byte called the 'termination character'.



When you call strlen you obtain the number of characters in the string, excluding the termination character that marks its end. This causes two problems:




  • When you loop to copy the string, you are not copying the termination character. Your string will therefore end at the next byte in memory that happens to be a zero, which could be anywhere. You're seeing the result of undefined behaviour: there's no reason why 12 characters should not work when other numbers do, it's just a consequence of your specific circumstances.

  • If you were to add the termination character, you'd be overflowing your destination string buffer, because your call to malloc also doesn't allocate enough space for the termination character.


While I'm here, I might as well also refer you to the ARM ABI, and specifically the part about the procedure call standard. While the ABI does not rule out using r0-r3 for intermediate values, these registers (along with r12) are 'call-clobbered' so it is typical to use r4-r11 for intermediate calculation. Functions must preserve r4-r11, usually by using the stack. Your use of r5 to hold a function argument (to store) is therefore contrary to the ABI, so your store function would not be callable from ABI-compliant code; and your pushing/popping of r1-r3 in several places is unnecessary if your callers also conform to the ABI. Also of note is that the ABI requires 8-byte stack alignment across function calls in different translation units, so it's a good idea to get into the habit of pushing and popping even numbers of registers to maintain this. (If you call a library function like malloc or strlen without ensuring 8-byte alignment, for example, you could run into undefined behaviour again.)






share|improve this answer





















  • Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
    – frog spit
    Nov 22 at 13:50












  • There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
    – cooperised
    Nov 22 at 15:45










  • I did but I don’t have enough posts or whatever for it to count, thank you though!
    – frog spit
    Nov 23 at 0:40















up vote
1
down vote



accepted










Strings, by convention, are terminated by a zero byte called the 'termination character'.



When you call strlen you obtain the number of characters in the string, excluding the termination character that marks its end. This causes two problems:




  • When you loop to copy the string, you are not copying the termination character. Your string will therefore end at the next byte in memory that happens to be a zero, which could be anywhere. You're seeing the result of undefined behaviour: there's no reason why 12 characters should not work when other numbers do, it's just a consequence of your specific circumstances.

  • If you were to add the termination character, you'd be overflowing your destination string buffer, because your call to malloc also doesn't allocate enough space for the termination character.


While I'm here, I might as well also refer you to the ARM ABI, and specifically the part about the procedure call standard. While the ABI does not rule out using r0-r3 for intermediate values, these registers (along with r12) are 'call-clobbered' so it is typical to use r4-r11 for intermediate calculation. Functions must preserve r4-r11, usually by using the stack. Your use of r5 to hold a function argument (to store) is therefore contrary to the ABI, so your store function would not be callable from ABI-compliant code; and your pushing/popping of r1-r3 in several places is unnecessary if your callers also conform to the ABI. Also of note is that the ABI requires 8-byte stack alignment across function calls in different translation units, so it's a good idea to get into the habit of pushing and popping even numbers of registers to maintain this. (If you call a library function like malloc or strlen without ensuring 8-byte alignment, for example, you could run into undefined behaviour again.)






share|improve this answer





















  • Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
    – frog spit
    Nov 22 at 13:50












  • There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
    – cooperised
    Nov 22 at 15:45










  • I did but I don’t have enough posts or whatever for it to count, thank you though!
    – frog spit
    Nov 23 at 0:40













up vote
1
down vote



accepted







up vote
1
down vote



accepted






Strings, by convention, are terminated by a zero byte called the 'termination character'.



When you call strlen you obtain the number of characters in the string, excluding the termination character that marks its end. This causes two problems:




  • When you loop to copy the string, you are not copying the termination character. Your string will therefore end at the next byte in memory that happens to be a zero, which could be anywhere. You're seeing the result of undefined behaviour: there's no reason why 12 characters should not work when other numbers do, it's just a consequence of your specific circumstances.

  • If you were to add the termination character, you'd be overflowing your destination string buffer, because your call to malloc also doesn't allocate enough space for the termination character.


While I'm here, I might as well also refer you to the ARM ABI, and specifically the part about the procedure call standard. While the ABI does not rule out using r0-r3 for intermediate values, these registers (along with r12) are 'call-clobbered' so it is typical to use r4-r11 for intermediate calculation. Functions must preserve r4-r11, usually by using the stack. Your use of r5 to hold a function argument (to store) is therefore contrary to the ABI, so your store function would not be callable from ABI-compliant code; and your pushing/popping of r1-r3 in several places is unnecessary if your callers also conform to the ABI. Also of note is that the ABI requires 8-byte stack alignment across function calls in different translation units, so it's a good idea to get into the habit of pushing and popping even numbers of registers to maintain this. (If you call a library function like malloc or strlen without ensuring 8-byte alignment, for example, you could run into undefined behaviour again.)






share|improve this answer












Strings, by convention, are terminated by a zero byte called the 'termination character'.



When you call strlen you obtain the number of characters in the string, excluding the termination character that marks its end. This causes two problems:




  • When you loop to copy the string, you are not copying the termination character. Your string will therefore end at the next byte in memory that happens to be a zero, which could be anywhere. You're seeing the result of undefined behaviour: there's no reason why 12 characters should not work when other numbers do, it's just a consequence of your specific circumstances.

  • If you were to add the termination character, you'd be overflowing your destination string buffer, because your call to malloc also doesn't allocate enough space for the termination character.


While I'm here, I might as well also refer you to the ARM ABI, and specifically the part about the procedure call standard. While the ABI does not rule out using r0-r3 for intermediate values, these registers (along with r12) are 'call-clobbered' so it is typical to use r4-r11 for intermediate calculation. Functions must preserve r4-r11, usually by using the stack. Your use of r5 to hold a function argument (to store) is therefore contrary to the ABI, so your store function would not be callable from ABI-compliant code; and your pushing/popping of r1-r3 in several places is unnecessary if your callers also conform to the ABI. Also of note is that the ABI requires 8-byte stack alignment across function calls in different translation units, so it's a good idea to get into the habit of pushing and popping even numbers of registers to maintain this. (If you call a library function like malloc or strlen without ensuring 8-byte alignment, for example, you could run into undefined behaviour again.)







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 22 at 13:08









cooperised

1,226812




1,226812












  • Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
    – frog spit
    Nov 22 at 13:50












  • There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
    – cooperised
    Nov 22 at 15:45










  • I did but I don’t have enough posts or whatever for it to count, thank you though!
    – frog spit
    Nov 23 at 0:40


















  • Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
    – frog spit
    Nov 22 at 13:50












  • There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
    – cooperised
    Nov 22 at 15:45










  • I did but I don’t have enough posts or whatever for it to count, thank you though!
    – frog spit
    Nov 23 at 0:40
















Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
– frog spit
Nov 22 at 13:50






Thank you! The 8 byte alignment probably has something to do with it. The strlen function is of my own design and does work how you described. Using on the string I just got from c_ascz, my user input service call function, it returns the string length plus 2 for some reason. In all other circumstances it rwturns the string length without the null. So after c_ascz I subtract one to have string length + 1 in R0. I then malloc that. Then at the end of the store function inside input, I do store the null terminator. Like I said the junk really only appears on all strings of length 12
– frog spit
Nov 22 at 13:50














There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
– cooperised
Nov 22 at 15:45




There's no magic to 12 though. Perhaps try to find out where the +2 is coming from in your string length calculation, rather than just subtracting one and hoping for the best?
– cooperised
Nov 22 at 15:45












I did but I don’t have enough posts or whatever for it to count, thank you though!
– frog spit
Nov 23 at 0:40




I did but I don’t have enough posts or whatever for it to count, thank you though!
– frog spit
Nov 23 at 0:40


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53424896%2farm-assembly-junk-only-on-strings-of-length-12%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Berounka

Fiat S.p.A.

Type 'String' is not a subtype of type 'int' of 'index'