Ошибка при изменении строк на неправильные значения при попытке перевернуть строку в x86-64Linux

Ответить
Anonymous
 Ошибка при изменении строк на неправильные значения при попытке перевернуть строку в x86-64

Сообщение Anonymous »

Я пытался написать простую подпрограмму (без стека) в стиле x86-64 nasm Intel для преобразования целых чисел в соответствующие строковые формы. Он был собран и скомпонован без ошибок, но при запуске исполняемого файла я обнаружил ошибку: вместо вывода «1691» из 1691 вывод был «1432» из следующего кода: -

Код: Выделить всё

section .data

section .bss
str_digits resb 100

section .text
global _start

_start:
mov rax, 1691
call _int_to_str
call _exit

_int_to_str:
mov rbx, 10
mov rcx, 0

_conversion_loop:
mov rdx, 0
div rbx
add rdx, 48
mov [str_digits + rcx], dl
inc rcx
cmp rax, 0
jne _conversion_loop

mov rbx, [str_digits]
mov rdx, rcx

_reverse_string:
mov [str_digits + rcx], bl
inc rbx
dec rcx
cmp rcx, 0
jne _reverse_string

_output_string:
mov rax, 1
mov rdi, 1
mov rsi, str_digits
syscall
ret

_exit:
mov rax, 60
mov rdi, 0
syscall

Я на самом деле почти уверен, что проблема возникла в функции _reverse_string, а именно в строке "mov [str_digits + rcx], bl", потому что, если вы удалите _conversion_loop из кода, на выходе будет "1961", что правильно, и именно поэтому строку необходимо перевернуть перед выходным системным вызовом, но в любом случае я не мог понять, почему код логически неверен и вызывает такую ошибку вот почему я дополнительно отладил: -
Во-первых, я дважды проверил, разрешено ли выражение "mov [str_digits + rcx], bl" и оно действительно.
Во-вторых, я использовал GDB для исполняемого файла следующим образом:-

Код: Выделить всё

(gdb) disass
Dump of assembler code for function _reverse_string:
=> 0x000000000040103f : mov    BYTE PTR [rcx+0x402000],bl
0x0000000000401045 : inc    rbx
0x0000000000401048 : dec    rcx
0x000000000040104b :    cmp    rcx,0x0
0x000000000040104f :    jne    0x40103f 
End of assembler dump.
(gdb) info reg rcx
rcx            0x4                 4
(gdb) info reg rbx
rbx            0x31363931          825637169
(gdb) info reg bl
bl             0x31                49
(gdb) n
Single stepping until exit from function _reverse_string,
which has no line number information.

Breakpoint 1, 0x000000000040103f in _reverse_string ()
(gdb) info reg rcx
rcx            0x3                 3
(gdb) info reg rbx
rbx            0x31363932          825637170
(gdb) info reg bl
bl             0x32                50
(gdb) n
Single stepping until exit from function _reverse_string,
which has no line number information.

Breakpoint 1, 0x000000000040103f in _reverse_string ()
(gdb) info reg rcx
rcx            0x2                 2
(gdb) info reg rbx
rbx            0x31363933          825637171
(gdb) info reg bl
bl             0x33                51
(gdb) n
Single stepping until exit from function _reverse_string,
which has no line number information.

Breakpoint 1, 0x000000000040103f in _reverse_string ()
(gdb) info reg rcx
rcx            0x1                 1
(gdb) info reg rbx
rbx            0x31363934          825637172
(gdb) info reg bl
bl             0x34                52
(gdb) n
Single stepping until exit from function _reverse_string,
which has no line number information.

Breakpoint 2, 0x0000000000401051 in _output_string ()
(gdb) info reg rcx
rcx            0x0                 0
(gdb) info reg rbx
rbx            0x31363935          825637173
(gdb) info reg bl
bl             0x35                53
(gdb) disass
Dump of assembler code for function _output_string:
=>  0x0000000000401051 : mov    eax,0x1
0x0000000000401056 : mov    edi,0x1
0x000000000040105b :    movabs rsi,0x402000
0x0000000000401065 :    syscall
0x0000000000401067 :    ret
End of assembler dump.

что, честно говоря, просто добавило больше вопросов, например, почему здесь "82 56 37 17 3" вместо предполагаемой десятичной последовательности, откуда взялось целое число 3, а 82 56 37 17 не являются "1961", а затем значение bl в bl каждый раз по какой-то причине неверно, за исключением 1-го, всегда даже с разными числами, например
2692 -> "2543", 1692 -> «2543», 1961 -> «1432», но на этом все не заканчивается, когда число имеет тенденцию заканчиваться на 9, например 18259, он выводит «9= «9=

Подробнее здесь: https://stackoverflow.com/questions/798 ... ing-in-x86
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»