Is there any way of passing bytes this way?
mov ecx, byte ["mybytes",0xa,0]
instead of:
section .data
mybytes db "mybytes",0xa,0
section .text
global main
main:
mov ecx, mybytes
Based on an example from the NASM manual, I have created a perfect macro:
%macro print 1+
[section .rodata] ; switch sections without updating the macro
%%data db %1 ; expand all the macro args
%%dataLen equ $- %%data
; db 0 ; optional 0 terminator outside the calculated length
; only useful if you need an implicit-length C string
__?SECT?__ ; switch back to the user's section
mov eax, 4
mov ebx, 1
mov ecx, %%data
mov edx, %%dataLen
int 0x80
%endmacro
and now i can simply print "string"
and it works!
The 1+
number of params allows it to be used like print "string", 0xa
to include a newline.
To just put a pointer in a register, you could write a macro like
%macro string_ptr 2+
[section .rodata]
%%data db %2
; db 0 ; optional 0 terminator baked into the macro
__?SECT?__
mov %1, %%data ; or lea %1, [rel %%data] for 64-bit
%endmacro
; use like this:
string_ptr ecx, "hello", 0xa, "world", 0
push ecx
call puts
A fancier macro might allow push %%data
to avoid wasting instructions getting it into a register first, for 32-bit stack-arg calling conventions. Or a separate macro that pushes, instead of making one flexible but complex macro.