最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

linux - How can I find out the length of an inputted string in assembly? - Stack Overflow

programmeradmin3浏览0评论

I am trying to build a small text editor (first project in assembly) and I happen to need to find out the length of a string to give person error. This input will be used to open or create files in the future but my code does not give me any outputs in the get_length label.
I tried to make input length not only eax but ebx, ecx and edx but there was no result.

This is my code:

section .data
  filename db 'test.txt'
  introduce db 'Put file name here: '

section .bss
  input resb 10
  input_length resb 1

section .text
  global _start

_start:
  ;printing introduce text
  mov eax, 4      ;system_write
  mov ebx, 1      ;std_out
  mov ecx, introduce  ;introduce text
  mov edx, 20     ;bytes to output
  int 0x80      ;make system call

  ;reading user input
  mov eax, 3      ;system_read
  mov ebx, 0      ;std_in
  mov ecx, input    ;info pointer
  mov edx, 10     ;read 10 bytes
  int 0x80      ;make system call

  ;unconditional jump to get_length label
  mov [input_length], eax 
  cmp edx, 10
  jl get_length 

  get_length:
    ;printing user's input
    mov eax, 4      ;system_write
    mov ebx, 1      ;std_out
    mov ecx, [input_length]   ;user's input
    mov edx, 10     ;bytes to write
    int 0x80      ;make system call

  mov eax, 1      
  int 0x80 

Also my CPU is x86 architecture and I am using linux (debian).

I am trying to build a small text editor (first project in assembly) and I happen to need to find out the length of a string to give person error. This input will be used to open or create files in the future but my code does not give me any outputs in the get_length label.
I tried to make input length not only eax but ebx, ecx and edx but there was no result.

This is my code:

section .data
  filename db 'test.txt'
  introduce db 'Put file name here: '

section .bss
  input resb 10
  input_length resb 1

section .text
  global _start

_start:
  ;printing introduce text
  mov eax, 4      ;system_write
  mov ebx, 1      ;std_out
  mov ecx, introduce  ;introduce text
  mov edx, 20     ;bytes to output
  int 0x80      ;make system call

  ;reading user input
  mov eax, 3      ;system_read
  mov ebx, 0      ;std_in
  mov ecx, input    ;info pointer
  mov edx, 10     ;read 10 bytes
  int 0x80      ;make system call

  ;unconditional jump to get_length label
  mov [input_length], eax 
  cmp edx, 10
  jl get_length 

  get_length:
    ;printing user's input
    mov eax, 4      ;system_write
    mov ebx, 1      ;std_out
    mov ecx, [input_length]   ;user's input
    mov edx, 10     ;bytes to write
    int 0x80      ;make system call

  mov eax, 1      
  int 0x80 

Also my CPU is x86 architecture and I am using linux (debian).

Share Improve this question edited Mar 29 at 19:20 Sep Roland 39.9k10 gold badges48 silver badges88 bronze badges asked Mar 26 at 12:51 skami0_0skami0_0 413 bronze badges 2
  • 1 ecx needs the text to write, edx needs the length. So you should do mov ecx, input; mov edx [input_length]. – Jester Commented Mar 26 at 12:56
  • 2 You also want input_length: resd 1 not resb 1; it's a 32-bit integer not a single byte. resb 4 would also work, but resd 1 (one dword) has the right semantic meaning. Anyway, use strace ./a.out to trace the system calls your process makes. – Peter Cordes Commented Mar 26 at 13:09
Add a comment  | 

1 Answer 1

Reset to default 2

I tried to make input length not only eax but ebx, ecx and edx but there was no result.

This is never going to be a good idea. The choice is not yours! Whomever wrote the system function that you're going to invoke made that choice for you, and you must follow it. That is why you have to consult the manual(s)...

;unconditional jump to get_length label
mov [input_length], eax
cmp edx, 10
jl get_length
get_length:
  • Using resb 1, you defined input_length to be a single byte. Therefore you should not be writing a full dword (4 bytes) to that variable. Either use resd 1 (or resb 4), or else just write AL instead of EAX.
  • The comment about "unconditional jump" is misleading. The construct that compares EDX to 10 and then conditionally jumps to get_length already clearly conflicts with the comment, but sure, the execution will always reach get_length either by jumping or by falling through.
get_length:
 ;printing user's input

The main confusion is about what it is that you want to print. Do you want to output the actual characters that the user inputted? Or do you want to show how many characters (aka length) the user inputted?

  • the actual characters:

      mov edx, [input_length] ; count
      mov ecx, input          ; address
      mov ebx, 1              ; std_out
      mov eax, 4              ; system_write
      int 0x80                ; make system call
    
  • the number of characters:

      add byte [input_length], "0" ; (*)
      mov edx, 1              ; count
      mov ecx, input_length   ; address
      mov ebx, 1              ; std_out
      mov eax, 4              ; system_write
      int 0x80                ; make system call
    

(*) Only valid for those cases where the length is from 0 to 9. Adding "0" (48) converts a digit [0,9] into a character ["0","9"].

发布评论

评论列表(0)

  1. 暂无评论