Assembly 我的汇编代码为字符串长度额外计算一个字节
我编写了以下代码来阅读文本,计算长度并报告它。为了保持代码简单,我假设字符串的长度小于10个字符 我用于构建的代码是Assembly 我的汇编代码为字符串长度额外计算一个字节,assembly,64-bit,x86-64,nasm,Assembly,64 Bit,X86 64,Nasm,我编写了以下代码来阅读文本,计算长度并报告它。为了保持代码简单,我假设字符串的长度小于10个字符 我用于构建的代码是 nasm -f elf64 strlen.asm && ld strlen.o -o strlen && ./strlen 我有两个问题: 此代码编译为64位,而代码本身为32位。我应该应用什么更改使代码也变成64位 为什么应用程序总是额外报告一个字节的长度?理论上,它不计算空终止。给定的文本是否包括\x10或\x13 section.text
nasm -f elf64 strlen.asm && ld strlen.o -o strlen && ./strlen
我有两个问题:
\x10
或\x13
李>
section.text
全球启动
_开始:
; 显示提示信息
mov-edx,19;要写入的字节数-每个字母一个加上0Ah(换行字符)
mov ecx,txt_提示符;将消息字符串的内存地址移到ecx中
mov-ebx,1;写入标准输出文件
mov-eax,4;调用系统写入(内核操作码4)
int 80h
; 读取用户输入
mov-eax,3;将用户输入读入str
mov-ebx,0|
mov ecx,用户输入;|是,read()
也返回行尾字符。您可以使用调试器看到这一点。注意它不是\x10
,因为它是十六进制。十进制是10。对于64位,使用64位系统调用和寻址模式。和默认rel
。有一些链接。请注意,将其构建为64位将使其成为64位。只是它碰巧也是一个有效的64位程序,当作为Linux非饼图可执行文件(虚拟地址空间低32位中的静态地址)链接时,它正好工作。如果您使用了push ebx
或其他什么,它将不会进行汇编,因为这不是合法的64位模式指令。如果您使用的是mov esp,ebp
/ret.@Jester,谢谢。我可以在Ubuntu上使用哪个调试器?常用的调试器是gdb
,如果你喜欢的话,它有前端。@Jester,nasm
和gdb
配合得好吗?是的,read()
也返回行尾字符。您可以使用调试器看到这一点。注意它不是\x10
,因为它是十六进制。十进制是10。对于64位,使用64位系统调用和寻址模式。和默认rel
。有一些链接。请注意,将其构建为64位将使其成为64位。只是它碰巧也是一个有效的64位程序,当作为Linux非饼图可执行文件(虚拟地址空间低32位中的静态地址)链接时,它正好工作。如果您使用了push ebx
或其他什么,它将不会进行汇编,因为这不是合法的64位模式指令。如果使用mov esp,ebp
/ret.@Jester,谢谢。我可以在Ubuntu上使用哪个调试器?常用的调试器是gdb
,如果你喜欢的话,它有前端。@Jester,nasm
和gdb
配合得好吗?
section .text
global _start
_start:
; show prompt message
mov edx, 19 ; number of bytes to write - one for each letter plus 0Ah (line feed character)
mov ecx, txt_prompt ; move the memory address of our message string into ecx
mov ebx, 1 ; write to the STDOUT file
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 80h
; read the user input
mov eax, 3 ; Read user input into str
mov ebx, 0 ; |
mov ecx, user_input ; | <- destination
mov edx, 100 ; | <- length
int 80h ; \
; calculate the length
mov ebx, user_input ; move the address of our message string into EBX
mov eax, ebx ; move the address in EBX into EAX as well (Both now point to the same segment in memory)
strlen_nextchar:
cmp byte [eax], 0 ; compare the byte pointed to by EAX at this address against zero (Zero is an end of string delimiter)
jz strlen_finished ; jump (if the zero flagged has been set) to the point in the code labeled 'finished'
inc eax ; increment the address in EAX by one byte (if the zero flagged has NOT been set)
jmp strlen_nextchar ; jump to the point in the code labeled 'strlen_nextchar'
strlen_finished:
sub eax, ebx ; subtract the address in EBX from the address in EAX
add byte [txt_output+33], al
; show output message
mov edx, 34 ; number of bytes to write - one for each letter plus 0Ah (line feed character)
mov ecx, txt_output ; move the memory address of our message string into ecx
mov ebx, 1 ; write to the STDOUT file
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 80h
; exit code
mov ebx, 0
mov eax, 1
int 80h
section .data
txt_prompt: db 'Enter your message:', 0Ah
txt_output: db 'The string length is calculated: 0', 0Ah
section .bss
user_input: resb 100