问题
Possible duplicate exist, but I couldnt figure out how to apply this or othere solutions to similar problems so here I am.
I am creating a function that returns and integer as a string in x86 AT&T Assembly.
I have this code to declare the variable resdes
.
.data
.align 4
resdes: .long 12
resdes
now points to a memory location followed by 11 other bytes free for me to use (I have understood this correctly?).
I want to load one digit at a time from the integer into the bytes one by one. this is my code:
ifd:
movl (%esp, %ecx), %eax //This loads %eax with my int
movl resdes, %ecx //This is incorrect and causes errors later
inc %ecx
movl $10, %ebx //Division by 10 to basically do a modulo operation
cdq
divloop:
div %ebx
movb %dl, (%ecx) //This is where I move the digit into the memory
//And here I get the ERROR because (%ecx) does
//not contain the proper address
inc %ecx //And set the pointer to point to the next byte
cmp $0, %eax //If there are noe more digits left we are finished
je divfinish1
jmp divloop //I leave out alot of the code that I know
//work because it's not relevant
My problem is getting this actual address of resdes
into the %ecx
register, the first line in the above code. As far as I know the line moves the contents of the resdes
-address into %ecx
, and this is not what I want.
回答1:
You want to load ECX with a constant which will be computed at "assemble time". So use '$' as prefix: movl $resdes, %ecx
to get the offset of resdes as constant.
回答2:
OK, so I "solved" this on my own. I basically removed the memory-storage all together, and instead use the stack.
This does not answer my question about how to correctly get addresses, but it made my code work so I put it up here.
ifd:
movl (%esp, %ecx), %eax
add $4, %ecx
movl $10, %ebx
pushl $0
divloop:
cdq
div %ebx
add $48, %edx
pushl %edx
cmp $0, %eax
je divfinish1
jmp divloop
divfinish1:
movl tempb, %ebx
divfinish2:
popl %edx
cmp $0, %edx
je divfinish3 //this is the end
movb %dl, (%ebx)
inc %ebx
jmp divfinish2
回答3:
The problem seems to be that you don't save the result of the division in the %ebx register after performing a division, and thus the division keeps on going forever, always returning the same modulo and division result -- you keep on dividing the same number. This, in turn, leads to a SIGSEGV because the result eventually overflows the 12 bytes reserved for the result. Here's a possible solution:
ifd:
movl resdes, %ecx
inc %ecx
movl $10, %ebx
cdq
divloop:
div %ebx
movb %dl, (%ecx)
inc %ecx
movl %eax,%ebx //Stores the new value in %ebx
cmp $0, %eax
je divfinish1
jmp divloop
resdes now points to a memory location followed by 11 other bytes free for me to use (I have understood this correctly?).
Yes.
来源:https://stackoverflow.com/questions/23383393/getting-address-of-data-variable-in-x86-att-assembly