Problem beim Erstellen einer Unterroutine zur dynamischen Ausgabe von Zeichenfolgen ohne Verwendung des Stacks in x86-64Linux

Linux verstehen
Anonymous
 Problem beim Erstellen einer Unterroutine zur dynamischen Ausgabe von Zeichenfolgen ohne Verwendung des Stacks in x86-64

Post by Anonymous »

Ich hatte eine Unterroutine zum dynamischen Drucken eines Strings, ohne die Länge des Strings manuell im x86-64-Intel-Stil aufzulisten, durch folgenden Code (mit Stack) :-

Code: Select all

section .data
output1 db "hello world",10,0
output2 db "hello world again",10,0

section .bss

section .text
global _start

_start:
mov rax,output1
call _output

mov rax,output2
call _output

call _exit

_output:
_output_setup:
push rax
mov rbx, 0

_output_length_loop:
inc rax
inc rbx

mov cl,[rax]

cmp cl, 0
jne _output_length_loop

_output_output:
mov rax, 1
mov rdi, 1
pop rsi
mov rdx, rbx
syscall
ret

_exit:
mov rax, 60
mov rdi, 0
syscall
ret
aber ich wollte die Unterroutine ohne Stapel, also habe ich versucht, die Unterroutine so zu schreiben, dass sie das Gleiche ohne Verwendung des Stapels tut, indem ich Folgendes durchführe:-

Code: Select all

section .data
output1 db "hello world",0
output2 db "again hello world",0

section .bss

section .text
global _start

_start:
mov rcx,output1
call _output
call _exit

_output:
mov rbx,0

_length_loop:
inc rbx
inc rcx
mov dl,[rcx]
cmp dl,0
jne _length_loop

_system_call:
mov rax,1
mov rdi,1
mov rsi,rcx
mov rdx,rbx
syscall
ret

_exit:
mov rax,60
mov rdi,0
syscall
ret

aber zu meiner Überraschung wurde „schon wieder die Hölle“ ausgegeben, sodass es so aussieht, als würde „output1-output-call“ die Zeichen von „output2“ drucken, aber ich habe noch nicht einmal einen Ausgabeaufruf von „output2“ gemacht, aber aus irgendeinem Grund nimmt es die richtige Länge von „output1“ im Register „rbx“, aber die falschen Bytes für „rcx“, aber das macht keinen Sinn, weil die Länge in „rbx“ in direkter Beziehung zu „rcx“ berechnet wird, was bedeutet, dass „rcx“ oder „value“ falsch ist rbx oder length sollten ebenfalls falsch sein, aber das ist nicht der Fall, also habe ich versucht, über gdb zu debuggen, und es zeigte Folgendes:-

Code: Select all

(gdb) info function
All defined functions:

Non-debugging symbols:
0x0000000000401000  _start
0x0000000000401014  _output
0x0000000000401019  _length_loop
0x0000000000401026  _system_call
0x0000000000401039  _exit
(gdb) break _system_call
Breakpoint 1 at 0x401026
(gdb) run
Starting program: /home/maybe/code/x86/linux/test2

This GDB supports auto-downloading debuginfo from the following URLs:

Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.

Breakpoint 1, 0x0000000000401026 in _system_call ()
(gdb) info register rbx
rbx            0xb                 11
(gdb) info register rcx
rcx            0x40200b            4202507

Dies zeigt zwar, dass das rbx-Register korrekt ist, aber der Wert im rcx-Register ist 4202507, was in ASCII in „ú“ übersetzt wird (Hinweis: Ich habe den ASCII-Wert mit einer zufälligen Dezimalzahl in eine ASCII-Website im Web übersetzt), aber das bedeutet dann, dass ich etwas falsch interpretiert habe, weil diese Dosis nicht mit dem Text auf dem Bildschirm übereinstimmt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post