I'm having trouble writing what should be a simple character counting program. Here's the file with the .data section, as given by the author of Learn to Program with Assembly, which I'm following (I posted it in another question a few days ago):
.section .data
gkcname: .ascii "Gilbert Keith Chester\0"
jbname: .ascii "Jonathan Bartlett\0"
cslname: .ascii "Clist Silver Lewis\0"
taname: .ascii "Tommy Aquinas\0"
inname: .ascii "Isaac Newn\0"
gmname: .ascii "Gregory Mend\0"
.globl people, numpeople
numpeople: .quad (endpeople-people)/PERSON_RECORD_SIZE
people:
.quad gkcname, 200, 10, 2, 74, 20
.quad jbname, 280, 12, 2, 72, 44
.quad cslname, 150, 8, 1, 68, 30
.quad taname, 250, 14, 3, 75, 24
.quad inname, 250, 10, 2, 70, 11
.quad gmname, 180, 11, 5, 69, 65
endpeople:
.globl NAME_PTR_OFFSET, WEIGHT_OFFSET, SHOE_OFFSET
.globl HAIR_OFFSET, HEIGHT_OFFSET, AGE_OFFSET
.equ NAME_PTR_OFFSET, 0
.equ WEIGHT_OFFSET, 8
.equ SHOE_OFFSET, 16
.equ HAIR_OFFSET, 24
.equ HEIGHT_OFFSET, 32
.equ AGE_OFFSET, 40
.globl PERSON_RECORD_SIZE
.equ PERSON_RECORD_SIZE, 48
And here is the file with the .text section, which is the part I'm trying write myself:
.section .text
_start:
movq $people, %rbx
movq (%rbx), %rax
movq numpeople, %rcx
mainloop:
cmpq $0, NAME_PTR_OFFSET(%rax)
je endloop
incq %rdi
loopcontrol:
incq %rax
jmp mainloop
endloop:
movq $60, %rax
syscall
Eventually the idea is to count the characters in each name and find which one is longest. That's the exercise. In C/C++ or Python, I'd have no issue with it. Right now, though, I'm just trying to get as far as counting the characters in the first name. I was trying to return that value via %rdi and ran into trouble already.
If I run movq NAME_PTR_OFFSET(%rax), %rdi, %rdi will return 71 (ASCII value for 'G', which is, indeed, the first letter of the first name), and if I incq %rax and then perform the same command, it will return 105 (ASCII for 'i'), so that's all working as expected. But somehow when I run it through the cmp command, something goes wrong.
The key command here (I think) is cmpq $0, NAME_PTR_OFFSET(%rax). What I'm going for with this, as you might guess, is to have %rdi increment by one each iteration through the loop until we reach the terminating null character ('\0', which is zero in ASCII). But when I run the program I get a value of 98 for %rdi, which I think is the total character count for all six names combined.
Also, to try to troubleshoot this, I ran cmpq $105, NAME_PTR_OFFSET(%rax) expecting that %rdi would come back with a value of one (105 is ASCII for 'i', the second character in the first name, so %rdi should increment once and then the loop should terminate). That gave me a segfault.
I'm sure this is something simple with my syntax or something, but I can't find a solution. The comparison functionality isn't working, and I can't figure out what I need to do differently.
cmpb(compare a byte item) notcmpq(compare a qword).cmpbfirst but I think I had the arguments reversed at that time (my high-level-programming mind tells me the order of the arguments shouldn't matter for this command, so I had to look it up to understand howcmpactually works), and by the time I figured that out I had already moved on to tryingcmpandcmpq. Anyways, much appreciated.movq NAME_PTR_OFFSET(%rax), %rdi, %rdi will return 71. No, DIL will have that value, the rest of RDI will have"ilbert ". You're making the same error as your last question, using an exit status to look at the low 8 bits of RDI instead of using a debugger. See the bottom of stackoverflow.com/tags/x86/info for GDB tips.0, which is only true at_startin a statically-linked Linux executable, and then only as an implementation detail, not a documented guarantee. In a dynamic executable's_start, or in any function, RDI holds arbitrary garbage from its last use (e.g. fromld.socode that ran in your process before your_start.) Either put a comment documenting that code-golf size-saving hack, or putxor %edi, %edibefore your strlen loop.movq NAME_PTR_OFFSET(%rbx), %raxinstead ofmovq (%rbx), %raxand thencmpb $0, (%rax)-- it does not make a difference in your case, sinceNAME_PTR_OFFSEThappens to be 0.