0

I am wondering how can I properly null-terminate a string in assembly language: what I did was simply setting movq $0, (position_to_terminate) and I thought this will terminate my string. However, there are still a lot of stuff after the null-terminator when I print the buffer out:

58   ASSERT(0 == strcmp(buf, "48"));
(gdb) print buf
$1 = "48\000\000\000\000\000\000\000\000\246\367\377\177\000"
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400a78 in testFormatByteAsHex (objs=objs@entry=0x603690)

I am really confused by this because this works in c, is there any other way to terminate a string in assembly language? Thank you in advance.This is the assembly function that I wrote: The purpose of this function is to read 2 parameters, first one being a value from 0 to 255(%rdi) and the second one being an array of length>=2(%rsi) and store the hexadecimal representation in the %rsi array.

hex_format_byte_as_hex:
    subq $8,%rsp
    movq $0,%r10
    movq $0,%rdx
    

.Lhex_format:
    cmpq $1,%r10
    jg .Lreturn1
    
    movq %rdi,%rax /*store input into %rax*/
    movq $16,%rbx  /*store 16 into %rbx*/
    idivq %rbx     /*store dividend in rax, and remainder in rdx*/

    cmpq $10,%rdx
    jge .Lhex
    addq $48,%rdx
    jmp .Lstore

.Lhex:
    addq $87,%rdx
.Lstore:
    movq %rdx,(%rsi,%r10) /*store remainder in %rsi[0]*/
    addq $1,%r10 /*increase %r10 by 1*/
    movq $0,%rdx
    movq %rax,%rdi
    
    jmp .Lhex_format

.Lreturn1:
    
    movq $0,%r11
    movq $1,%r10
    
    movq (%rsi,%r10),%r12
    movq (%rsi,%r11),%r13
    movq %r12,(%rsi,%r11)
    movq %r13,(%rsi,%r10)

    
    
    movq $2,%r10
    movb $0,(%rsi,%r10)
    addq $8,%rsp


    ret
Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
M. Chen
  • 203
  • 1
  • 6
  • 2
    There will always be stuff after your string (unless you hit an unmapped page). Apparently `gdb` is printing your `buf` as an array and not a string. Use `p/s buf` or similar. PS: yeah using 8 zeroes is overkill (and will possibly overflow your buffer, depending on circumstances). – Jester Sep 29 '20 at 00:03
  • 4
    Every time you use `idiv` with a power of 2, an electron cries. Also, your hex digits are backwards: you're getting the low digit but storing in *increasing* order. That's opposite of printing order. See [How to convert a binary integer number to a hex string?](https://stackoverflow.com/q/53823756) for int->hex that doesn't suck. Easy to extend to 64-bit input / 16-byte ASCII hex output, with a 64-bit calling convention or just inline it. (It doesn't 0-terminate; add that separately after the loop, or print with fixed-width output like `fwrite` or `write`) – Peter Cordes Sep 29 '20 at 00:04
  • 2
    See also [Printing an integer as a string with AT&T syntax, with Linux system calls instead of printf](https://stackoverflow.com/q/45835456) for a base 10 function that stores backwards into a buffer. – Peter Cordes Sep 29 '20 at 00:08

0 Answers0