NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: proteusguy on October 11, 2017, 04:40:06 AM
-
Definitely has to be something stupid I'm missing but I can't get the correct value out of my CountedString.length as you can see from executing the code below. Appreciate any clues as to what I'm doing wrong as I've tried a dozen or so different things with no improvement.
struc CountedString
.length: resb 1
.str_ptr: resd 1
; .ref_count: resw 1
.counted_string_struc_size:
endstruc
global system_exit
SECTION .text
system_exit: ; terminates the running app cleanly.
xor ebx,ebx ; 0 is normal exit code for linux sys_exit call
;mov eax,1 ; sys_exit call id is 1
xor eax,eax ; xor then inc is one byte shorter than direct assignment of literal
inc eax
int 0x80 ; call linux kernel
global main
SECTION .text
startup_msg: db "Test machine v 0.01 startup.", 10, 0
startup_msg_len: equ $-startup_msg
startup_string:
istruc CountedString
at CountedString.length, db startup_msg_len
at CountedString.str_ptr, dd startup_msg
; at CountedString.ref_count, dw 0ffffh
iend
main:
; print out our startup message then exit.
mov edx, startup_msg_len
mov ecx, startup_msg
mov ebx, 1 ; stdout file handle
mov eax, 4 ; sys_write call id
int 0x80
mov edx, startup_string + CountedString.length
mov ecx, [startup_string + CountedString.str_ptr]
mov ebx, 1 ; stdout file handle
mov eax, 4 ; sys_write call id
int 0x80
call system_exit ; exit application
In case it matters, I'm building this on NASM version 2.10.09 compiled on Dec 29 2013 under Kubuntu 14.04 using the following commands:
nasm -f elf64 -l machine_core.lst machine_core.asm
gcc -m64 -o machine machine_core.o
on a laptop with: uname -a
Linux satriani 4.4.0-97-generic #120~14.04.1-Ubuntu SMP Wed Sep 20 15:53:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
-
Hi proteusguy,
Welcome to the forum.
There are a couple of issues here. Mainly, since you put the length in edx, it wants to be dword, not byte. Although the length would fit in a byte, by doing "mov edx..." we move four bytes - the length and the first three bytes of the string! Using "movzx edx, byte..." would also fix it.
; nasm -f elf32 this.asm
; ld -o this this.o -e main
struc CountedString
.length: resd 1
.str_ptr: resd 1
; .ref_count: resw 1
; don't need this
.counted_string_struc_size:
endstruc
; Nasm essentially does CountedString_size equ $ - CountedString
; don't need this since it's here - doesn't hurt
global system_exit
SECTION .text
system_exit: ; terminates the running app cleanly.
xor ebx,ebx ; 0 is normal exit code for linux sys_exit call
;mov eax,1 ; sys_exit call id is 1
xor eax,eax ; xor then inc is one byte shorter than direct assignment of literal
inc eax
int 0x80 ; call linux kernel
; ask nasm to tell linker about this entrypoint
global main
section .data
; SECTION .text
; don't need the terminating zero - doesn't hurt
startup_msg: db "Test machine v 0.01 startup.", 10, 0
startup_msg_len: equ $-startup_msg
startup_string:
istruc CountedString
at CountedString.length, dd startup_msg_len
at CountedString.str_ptr, dd startup_msg
; at CountedString.ref_count, dw 0ffffh
iend
section .text
main:
; print out our startup message then exit.
mov edx, startup_msg_len
mov ecx, startup_msg
mov ebx, 1 ; stdout file handle
mov eax, 4 ; sys_write call id
int 0x80
mov edx, [startup_string + CountedString.length]
mov ecx, [startup_string + CountedString.str_ptr]
mov ebx, 1 ; stdout file handle
mov eax, 4 ; sys_write call id
int 0x80
call system_exit ; exit application
There are a couple trivial issues... "main" is known to the C language as the entrypoint. If you're using gcc, this is right. Since we have no C code here, we don't need to use gcc - although we can. I chose to link it directly with ld. ld knows "_start:" as the default entrypoint. We can tell it something else with the "-e" switch. Normally I would probably use "_start:", but for no good reason I used "-e main".
You also need the square brackets around the length. If we use "equ" it's an immediate number so no [] needed. But if we use "dd", as in the structure, it's a memory variable and we need 'em.
You've got the "struc" thing pretty well, it was these other issues that were giving you trouble.
Best,
Frank
-
Frank,
Thanks much for the help! I knew it was something simple. However I don't feel quite so bad as I still can't find anything in the documentation that would have gotten me a valid syntax. To wit - ultimately I need that CountedString.length to be 8-bits so your suggestion to use movzx was what I needed. Now - getting the movzx syntax correct was troublesome but I found some examples on the interweb that made me finally try this:
movzx edx, byte [startup_string + CountedString.length]
Now I can't find any nasm docs on that "byte" specification which was the final missing link. Did I miss something or is there a secret syntax reference out there? Anyway - appreciate your advice and patience! I can use STRUC now!
-
That's a good question! Nasm sometimes needs a "size specifier" - byte/word/dword/qword. For example:
mov [myvar], 42]
won't assemble. Nasm doesn't know what size of 42 we need, We need to do:
mov byte [myvar], 42
;or
mov [myvar], byte 42
Some time ago, there was a question here as to which was the preferred position for the size specifier. Either will work, in this case, but "movzx" (etc.) requires it to be with the source operand. I suggested that he might want to always put it with the source operand for consistency ( although I often don't do it). It must say that somewhere in the Manual, but I can't find it at the moment. I'll look some more...
When I wrote my last reply, I missed the fact that you were doing 64 bit code (and that you were, in fact, using gcc). What you've got there is 32 bit code. It will work, within limits, but if you want 64 bit code, you might want to use 64 bit system call numbers (they are different), put the parameters in 64 bit registers (they are different), and use "syscall" instead of "int 0x80". I'm still running a 32 bit machine, so I can't help you too much with that. Accessing the structure elements should be the same.
Best,
Frank