어셈블리의 문자열 목록 인쇄
Sep 18 2020
다음 프로그램은 문자열 목록을 인쇄하기 위해 어떻게 보입니까? 개선 할 수있는 곳은 무엇입니까? \n문자열 자체에 하드 코딩하는 것보다 각 문자열 다음에 줄 바꿈과 같은 것을 인쇄하는 더 쉬운 방법이 있습니까?
# Program, print out a list of strings, one per line
.data
SYS_EXIT = 60
SYS_WRITE = 1
SYS_STDOUT = 1
# Empty string means end of strings
strings: .asciz "Once\n", "upon\n", "a\n", "time\n", "...\n", ""
.text
.globl _start
get_string_length:
mov $0, %eax .L1_loop: movzbl (%edi, %eax), %ecx cmp $0, %cl
je .L1_exit
inc %eax
jmp .L1_loop
.L1_exit:
ret
_start:
mov $strings, %rbx print_loop: mov %rbx, %rdi call get_string_length # (rdi=file_descriptor, rsi=starting_address, rdx=size) cmp $0, %eax
jz exit
mov $SYS_STDOUT,%edi mov %rbx, %rsi mov %eax, %edx mov $SYS_WRITE, %eax
syscall
lea 1(%eax, %ebx,), %ebx
jmp print_loop
exit:
mov $0, %edi mov $SYS_EXIT, %eax
syscall
답변
3 SepRoland Sep 26 2020 at 05:59
이 있습니까 쉬운 방법 하드 코딩보다는 각 문자열 후 LINEBREAK 뭔가를 인쇄 할 수는 \ n 문자열 자체로?
삽입 된 줄 바꿈은 확실히이를 수행하는 가장 쉬운 방법이지만 확실히 가장 다재다능한 방법은 아닙니다. 줄 바꿈 종류를 포함하면 문자열이 출력에만 사용되는 방향으로 이동합니다. 당신은 그들과 함께 많은 다른 것들을 할 수도 있습니다.
나는 문자열을 순수하게 유지하고 나중에 줄 바꿈이나 다른 접두사 또는 접미사를 추가하는 것을 옹호합니다. 이미 문자열의 문자를 계산해야하므로 동시에 문자열을 버퍼에 복사 할 수 있습니다 (모든 중요하지 않은 프로그램에는 준비된 일부 범용 버퍼가 있습니다). 제로 종결자를 읽으면 버퍼에 개행 문자를 저장합니다. 이제 길이를 알고있는 버퍼 내용을 인쇄 할 준비가되었습니다.
아래 코드에서 PrepStringForOutput 은 리프 함수로, 원하는 모든 작업을 수행 할 수 있습니다. 레지스터 규칙 자체를 따를 필요가 없습니다.
# Program, print out a list of strings, one per line
.data
SYS_EXIT = 60
SYS_WRITE = 1
SYS_STDOUT = 1
# Empty string means end of strings
Strings: .asciz "Once", "upon", "a", "time", "...", ""
Buffer: .ascii "12345"
.text
.globl _start
; IN (%rbx is asciz) OUT (%rsi is buffer, %rdx is length) MOD (%al)
PrepStringForOutput:
mov $Buffer, %rsi # Destination xor %edx, %edx # Length .L1_loop: mov (%rbx, %rdx), %al # Character from asciz string test %al, %al jz .L1_exit mov %al, (%rsi, %rdx) # Store in buffer inc %edx jmp .L1_loop .L1_exit: mov $10, (%rsi, %rdx) # Adding newline
inc %edx
ret
_start:
mov $Strings, %rbx PrintLoop: cmpb $0, (%rbx) # End of list ?
je Exit
call PrepStringForOutput # -> %rsi is address, %rdx is length
add %rdx, %rbx # Advancing in the list
mov $SYS_STDOUT, %edi mov $SYS_WRITE, %eax
syscall
jmp PrintLoop
Exit:
xor %edi, %edi
mov $SYS_EXIT, %eax
syscall
개선 할 수있는 곳은 무엇입니까?
위의 코드에서 쉽게 찾을 수 있습니다
. 멋진 표 레이아웃이 보이 시나요?