我试图在程序集中存储一些字符串,并使用WriteString在屏幕上打印出来。但是,我只调用其中一个字符串,它在一行中显示所有字符串。为什么会这样?我的代码有什么问题吗?谢谢!
代码在这里:
%include "lib/libasm.h"
SECTION .text
global main
main:
call badrng
ret
badrng:
push eax
push edx
mov edx, badrngstr
call WriteString
pop edx
pop eax
call failure
ret
failure:
mov eax,1
int 0x80
ret
SECTION .data
nlstr: db ""
badrngstr: db "Value out of range in assignment"
baddivstr: db "Division by zero"
badcasstr: db "Value not handled in case statement"
badptrstr: db "Attempt to use a null pointer"
badsubstr: db "Subscript out of bounds"
stkovstr: db "Stack overflow"
heapovstr: db "Out of heap space"
和WriteString在libasm.s
中 EXTERN main
SECTION .text
GLOBAL _start
_start:
call main
mov ebx, eax
call Exit
ret
GLOBAL AsciiDigit
AsciiDigit: ; al = digit to convert
SECTION .data
.xtable db "0123456789abcdef"
SECTION .text
push ebx
mov ebx, .xtable
xlat
pop ebx
ret
GLOBAL Crlf
Crlf:
SECTION .data
.lf db 0x0a
.lflen equ $-.lf
SECTION .text
pusha
mov ecx, .lf
mov edx, .lflen
call Write
popa
ret
GLOBAL Exit
Exit: ; ebx = error code
mov eax, 0x01
int 0x80
ret
GLOBAL Strlen
Strlen: ; edi = string
push edi
mov eax, 0
.L1:
cmp byte [edi], 0 ; end of string?
je .L2
inc edi
inc eax
jmp .L1
.L2:
pop edi
ret
GLOBAL Write
Write: ; ecx = buffer, edx = count
push ebx
mov eax, 0x04 ; sys_write = 4
mov ebx, 1 ; fd = 1 (stdout)
int 0x80
pop ebx
ret
GLOBAL WriteChar
WriteChar: ; al = the char
SECTION .data
.bb db 0
SECTION .text
pushad
mov byte [.bb], al
mov ecx, .bb
mov edx, 1
call Write
popad
ret
GLOBAL WriteHex
WriteHex: ; eax = the number
SECTION .data
.buf TIMES 16 db 0 ; buffer
.bufsz equ $-.buf ; bufsize
SECTION .text
pushad
mov edi, .buf ; point to the string
add edi, .bufsz
mov ecx, 0 ; buflen
.L1:
mov ebx, eax ; preserv eax into ebx
and al, 0x0f
call AsciiDigit
dec edi
mov byte [edi], al
inc ecx
mov eax, ebx ; restore eax
shr eax, 4
or eax, eax ; eax == zero ?
jnz .L1
;
mov edx, ecx
mov ecx, edi
call Write
popad
ret
GLOBAL WriteInt
WriteInt: ; eax = the number
SECTION .data
.isneg db 0 ; negative = 0 (false)
.buf TIMES 16 db 0 ; buffer
.bufsz equ $-.buf ; bufsize
SECTION .text
pushad
mov byte [.isneg], 0 ; negative = 0 (false)
or eax, eax ; eax is positive?
jns .L1
neg eax
mov byte [.isneg], 1 ; negative = 1 (true)
.L1:
mov edi, .buf ; point to the string
add edi, .bufsz
mov ecx, 0 ; buflen
mov ebx, 10 ; divided by 10
.L2:
mov edx, 0 ; edx:eax = the number
div ebx ; eax = Q, edx = R
or dl, 0x30 ; convert value to ASCII
dec edi
mov byte [edi], dl
inc ecx
or eax, eax ; eax == zero ?
jnz .L2
; add the sign symbol
cmp byte [.isneg], 0
je .L3
dec edi
mov byte [edi], '-'
inc ecx
.L3:
mov edx, ecx
mov ecx, edi
call Write
popad
ret
GLOBAL WriteString
WriteString:
SECTION .text
pushad
mov edi, edx
call Strlen
mov ecx, edx
mov edx, eax
call Write
popad
ret
,输出结果为
Value out of range in assignmentDivision by zeroValue not handled in case statementAttempt to use a null pointerSubscript out of boundsStack overflowOut of heap space
我不知道为什么它会打印所有字符串,即使我只移动一个字符串edx。拜托,谁能告诉我哪里做错了?
注意:它在ubuntu 12.04 32bit上测试并运行。
答案 0 :(得分:2)
字符串必须以空值终止 - 您必须指示最后一个字节的零值。如果您希望输出例程将字符串放在其自己的行上,您可能还需要指示回车符和换行符。
您可以通过指定:
来执行此操作nullstr db 0
errorMessage db 'critical error', 10, 13, 0
warningMessage db 'warning', 10, 13, 0
goodbyeWorld1 db 'Goodbye World.', 0
goodbyeWorld2 db 'Goodbye World.'
endline db 10, 13, 0
endline
字符串的工作原理是,由于goodbyeWorld2
不是空终止,它会显示运输供稿和换行符的ascii代码,因此Goodbye World.
会显示在其上shell输出中的自己的行。但是,由于goodByeWorld1
为空终止,它不会出现在它自己的行上,输出将继续在最后的'。'。字符显示。