繁体   English   中英

Nasm:在控制台上打印

[英]Nasm: Print on console

我制作了这个程序来打开一个图像文件并在文件中找到隐藏的消息。 我必须在控制台上打印消息。

我认为我打开文件并搜索隐藏消息的部分是正确的,但我不确定,因为我无法打印 output 来确认。

这是代码:

; Example program to demonstrate file I/O.
; This example will open/create a file, write some
; information to the file, and close the file.
; Note, the file name is hard-coded for this example.
; This example program will open a file, read the
; contents, and write the contents to the screen.
; This routine also provides some very simple examples
; regarding handling various errors on system services.
; -------------------------------------------------------
section .data
; -----
; Define standard constants.
LF equ 10 ; line feed
NULL equ 0 ; end of string
TRUE equ 1
FALSE equ 0
EXIT_SUCCESS equ 0 ; success code
STDIN equ 0 ; standard input
STDOUT equ 1 ; standard output
STDERR equ 2 ; standard error
SYS_write equ 1; write
SYS_read equ 0 ; read
SYS_open equ 2 ; file open
SYS_close equ 3 ; file close
SYS_exit equ 60 ; terminate
SYS_creat equ 85 ; file open/create
SYS_time equ 201 ; get time
O_CREAT equ 0x40
O_TRUNC equ 0x200
O_APPEND equ 0x400
O_RDONLY equ 000000q ; read only
O_WRONLY equ 000001q ; write only
S_IRUSR equ 00400q
S_IWUSR equ 00200q
S_IXUSR equ 00100q
; -----
; Variables/constants for main.
BUFF_SIZE equ 256
newLine db LF, NULL
db LF, LF, NULL
fileName dq 6
fileDesc dq 0
errMsgOpen db "Error opening the file.", LF, NULL
errMsgRead db "Error reading from the file.", LF, NULL
offset db 1
size db 1
; -------------------------------------------------------
section .bss
readBuffer: resb BUFF_SIZE
; -------------------------------------------------------
section .text
global _start
_start:
xor rax, rax
xor rcx, rcx
xor rdx, rdx
xor rbx, rbx
mov rbx, rsp
mov rax, qword [rbx+16]
mov [fileName], rax
xor rax, rax
push rsp

; Attempt to open file - Use system service for file open

openInputFile:
pop rax ; pop argc value - should be 2
cmp rax, 0x2    
jne done
mov rax, SYS_open ; file open
mov rdi, fileName ; file name string
mov rsi, O_RDONLY ; read only access
syscall ; call the kernel
cmp rax, 0 ; check for success
jl errorOnOpen
mov qword [fileDesc], rax ; save descriptor
; -----
; Read from file.
;
mov rax, SYS_read
mov rdi, qword [fileDesc]
mov rsi, readBuffer
mov rdx, BUFF_SIZE
syscall
cmp rax, 0
jl errorOnRead
; -----
; Print the buffer.
; add the NULL for the print string
mov rax, qword [readBuffer+2] ;SSSS
mov qword [size], rax
mov rax, qword [readBuffer+10] ;OOOO
mov [offset], rax
mov rcx, 0


ler: ;ler um caracter
mov rbp, 0
xor rbx, rbx
xor rdx, rdx

lerloop:
inc rax
cmp rax, [size]
je errorOnRead

saltaQuartobyte:
inc ecx
cmp ecx, 4
jne continua
inc rax ;incremneta rax outra vez para saltar o quarto
cmp rax, [size]
je errorOnRead
mov ecx, 0

continua:
mov bl, byte [readBuffer+rax]
shl rdx, 1
shr rbx, 1
adc rdx, 0

inc rbp
cmp rbp, 7 ;fim do caracter ASCII, 0X 0XXX XXXX
jne lerloop

mov rdi, rdx
call printString ; imprime caracter ASCII

cmp rax, [size] ;comea o priximo
jne ler
; -----
; Close the file.

mov rax, SYS_close
mov rdi, qword [fileDesc]
syscall
jmp done
; -----
; Error on open.

errorOnOpen:
mov rdi, errMsgOpen
call printString
jmp done

; Error on read.

errorOnRead:
mov rdi, errMsgRead
call printString
jmp done
; -----
; program done.
done:
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall

; **********************************************************
; Generic procedure to display a string to the screen.

global printString
printString:
push rbp

mov rbp, rsp
push rbp
; -----
; Call OS to output string.
mov rax, SYS_write ; code for write()
mov rsi, rdi ; addr of characters
mov rdi, STDOUT ; file descriptor
; count set above
syscall ; system call
; -----
; String printed, return to calling routine.
prtDone:
pop rbx
pop rbp
ret

这是我最后一次尝试打印,但程序仍然没有打印任何东西,我不明白为什么? 或者怎么了?

一个根本性的错误

push rsp; Attempt to open file - Use system service for file open openInputFile: pop rax; pop argc value - should be 2 cmp rax, 0x2 jne done mov rax, SYS_open; file open

您的程序首先将堆栈指针RSP复制到累加器RAX ,然后进行比较以查看值是否为 2,但堆栈指针何时会变为 2 因此,程序总是会提前退出 难怪什么都没有打印出来。

其他错误的选择

offset db 1 size db 1... mov rax, qword [readBuffer+2];SSSS mov qword [size], rax mov rax, qword [readBuffer+10];OOOO mov [offset], rax

您保留的空间不足,无法存储 qwords大小偏移量

使用resq更好地将它们存储在 .bss 部分:

section .bss
readBuffer: resb BUFF_SIZE
offset      resq 1
size        resq 1

 mov rax, qword [readBuffer+2];SSSS mov qword [size], rax mov rax, qword [readBuffer+10];OOOO mov [offset], rax

如果文件是 a.BMP(我正在考虑那些众所周知的偏移量),那么sizeoffset字段实际上是dwords 您必须改为编写(加载EAX自动将零值扩展为RAX ):

mov   eax, [readBuffer+2] ;SSSS
mov   [size], rax
mov   eax, [readBuffer+10] ;OOOO
mov   [offset], rax

 printString: push rbp mov rbp, rsp push rbp <<<<... pop rbx <<<< pop rbp ret

由于不匹配,您在返回时会破坏RBX

您使用的代码取决于计算 ASCIIZ 字符串的长度。 你不能把它排除在外!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM