2

I am trying to print address of variable in NASM x86 assembly. When I assemble this code it assembles fine, however when I run this code it prints two characters instead of the address.

section .bss
Address: RESB 4

section .data
variable db 1

section .text
global _start
_start:
mov eax , variable           ; variable Address is stored in eax register
mov [Address] , dword eax    ; move the value of eax to Address
mov eax , 4                  ; write system call in linux
mov ebx , 1                  ; stdout file descriptor
mov ecx , Address            ; memory address to be printed.
mov edx , 4                  ; 4 bytes to be print
int 0x80
mov eax , 1
int 0x80

screenshot: for your reference

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Naveen prakash
  • 409
  • 1
  • 5
  • 10
  • 5
    The write system call does not print integers it prints strings. You need to convert the address to a string and then print the string – Michael Petch Nov 30 '17 at 07:03
  • @MichaelPetch GOT IT bro. how to convert the address to string bro? i searched in google but could not find appropriate results. – Naveen prakash Nov 30 '17 at 07:17
  • Check how `iota' C-function is implemented, it converts integer to string. Hint in assembler is here https://stackoverflow.com/questions/13523530/printing-an-int-or-int-to-string . – rafix07 Nov 30 '17 at 08:01
  • It is also quite common to use rather hexadecimal formatting for values like addresses and memory content, because in hexadecimal formatting each digit represents exactly 4 bits. So a 32 bit pointer then will result into exactly 8 hexadecimal digits = fixed width in logs/outputs. Plus converting the binary value into hexadecimal string is simpler+faster (it's just 4 bits => 1 digit straight mapping conversion), than decimal output, that one needs serious calculation. Check also: https://stackoverflow.com/tags/x86/info for various links – Ped7g Nov 30 '17 at 11:33
  • @Naveenprakash Split the address into digits and then convert each digit into ASCII. – fuz Nov 30 '17 at 12:28

1 Answers1

0

You should just format the output as hex number. You can use printf from C for this purpose

extern printf

section .bss
        Address: RESB 4

section .data
        variable db 1
        fmt db "0x%x", 10, 0         ; format string

section .text
global _start
_start:
        mov eax , variable           ; variable Address is stored in eax register
        mov [Address] , dword eax    ; move the value of eax to Address

        push dword [Address]         ; push value of Address
        push dword fmt               ; address of format string
        call printf                  ; calling printf
        add esp, 8                   ; pop stack 2*4 bytes after passing two variables to printf

        mov eax, 0                   ; exit code 0
        int 0x80
Yan Mazan
  • 1
  • 1
  • You should `call exit` after using stdio functions like printf, otherwise output will be lost if `stdout` is full-buffered (e.g. if you redirect to a file). Also, there's no point in storing the address to a separate static variable, or even loading it into a register first. `push variable` works just fine. – Peter Cordes Dec 08 '19 at 15:21
  • It's also generally not recommended to use `printf` from `_start`, although it does work on Linux as long as you *dynamically* link. If you link statically, glibc init function never get called and printf will crash. Oh, also, you're violating the i386 System V ABI by calling printf with ESP not aligned by 16. On entry to `_start`, ESP is aligned by 16, so you need an extra `sub esp, 8` before pushing args. – Peter Cordes Dec 08 '19 at 15:26