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
assembly raspberry-pi arm
add a comment |
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
assembly raspberry-pi arm
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
add a comment |
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
assembly raspberry-pi arm
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
assembly raspberry-pi arm
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
add a comment |
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
add a comment |
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.)
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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.)
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
add a comment |
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.)
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
add a comment |
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.)
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.)
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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