最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

assembly - Program runs forever and doesn't print anything to the console - Stack Overflow

programmeradmin3浏览0评论

i am trying to build a program that would print a value of each bit in AL into the console, because i want to see the time (in seconds) stored in eax. GDB says my program has received signal SIGSEGV, which indicates segmentation fault.

I have realized now that i had used pop instruction in my loop and push instruction before the loop, which resaulted in segmentation fault.

I have fixed it simply by moving the data to edi.

But now my fixed program doesn't output anything to the console. It seems like it runs forever.

Does anyone have any idea why?

Thanks a lot! Feel free to ask me questions about my shitty code.

SECTION .data
linefeed db 0xA,0xD

SECTION .bss

SECTION .text
global _start

_start:

mov eax,13 
int 80h 

;push eax 
mov edi,eax
mov bl,1
mov cl,0 

bitmaska:

shl bl,cl 

and al,bl 

shr al,cl 

shr bl,cl 

add al,48

mov edx,1 
movzx ecx,al 
mov ebx,1
mov eax,4
int 80h

;pop eax
 mov eax,edi

inc cl

cmp cl,8
jnz bitmaska 

konec:
mov edx,1
mov ecx,linefeed
mov ebx,1
mov eax,4
int 80h

mov ebx,0
mov eax,1
int 80h

i am trying to build a program that would print a value of each bit in AL into the console, because i want to see the time (in seconds) stored in eax. GDB says my program has received signal SIGSEGV, which indicates segmentation fault.

I have realized now that i had used pop instruction in my loop and push instruction before the loop, which resaulted in segmentation fault.

I have fixed it simply by moving the data to edi.

But now my fixed program doesn't output anything to the console. It seems like it runs forever.

Does anyone have any idea why?

Thanks a lot! Feel free to ask me questions about my shitty code.

SECTION .data
linefeed db 0xA,0xD

SECTION .bss

SECTION .text
global _start

_start:

mov eax,13 
int 80h 

;push eax 
mov edi,eax
mov bl,1
mov cl,0 

bitmaska:

shl bl,cl 

and al,bl 

shr al,cl 

shr bl,cl 

add al,48

mov edx,1 
movzx ecx,al 
mov ebx,1
mov eax,4
int 80h

;pop eax
 mov eax,edi

inc cl

cmp cl,8
jnz bitmaska 

konec:
mov edx,1
mov ecx,linefeed
mov ebx,1
mov eax,4
int 80h

mov ebx,0
mov eax,1
int 80h
Share Improve this question asked Feb 14 at 23:41 IlikeAssemblyButIsuck-sorryIlikeAssemblyButIsuck-sorry 355 bronze badges 3
  • 4 You know that cl is the low 8 bits of ecx, right? So movzx ecx,al will of course destroy cl. – Jester Commented Feb 14 at 23:44
  • 3 Also note that the write syscall expects a pointer to what you want to write. – Jester Commented Feb 15 at 0:12
  • @Jester Yeah i know, just overlooked it, thanks. :D – IlikeAssemblyButIsuck-sorry Commented Feb 16 at 20:01
Add a comment  | 

1 Answer 1

Reset to default 3

Express edit to address more issues from a comment. Currently my browser doesn't allow writing comments

mov eax,13
int 80h

There's trouble with that sys_time that is supposed to return in EAX the time as the number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). You fot to initialize the EBX argument. If EBX happened to be non-zero, then the service would have tried to additionally store the result in whatever memory EBX was pointing to. That's a good reason for a segmentation error! You should always zero the EBX register with this service:

xor   ebx, ebx             ; Don't need a copy in memory
mov   eax, 13              ; sys_time
int   80h                  ; -> EAX

But, if you did want a copy in a memory location, then just reserve room for it. Preferrably in the .bss section, but in the .data section would be fine too. You create it with: MyCopyOfTheTime dd 0 when in the .data section, or with MyCopyOfTheTime resd 1 when in the .bss section.
The actual retrieval then requires EBX pointing to this doubleword:

mov   ebx, MyCopyOfTheTime ; Want a copy in memory
mov   eax, 13              ; sys_time
int   80h                  ; -> EAX

You can use this copy from memory with the usual instructions. You can read from it with eg. mov eax, [MyCopyOfTheTime], and you write to it with eg. mov dword [MyCopyOfTheTime], 0.


The write operation within the loop messes with the other registers that your loop depends on! Moreover you didn't supply in ECX an address for this system call. And once it will work, you will notice that the output is in the reverse order because you begin at the lowest bit. The binary representation must have the most significant bit on the left side, so start at the highest bit.

I would suggest that you don't output while being in the loop, but store to memory, and then in the end you can output everything in one go.
To this effect you change the linefeed definition to be:

buffer   db '????????'
linefeed db 10

The 8 question marks are place-holders for your actual '0' and '1' characters. The final output then becomes:

konec:
 mov   edx, 9
 mov   ecx, buffer
 mov   ebx, 1
 mov   eax, 4
 int   80h

Now the core loop should be a simple one. No need to shift that many times by CL:

 mov   ebx, eax
 mov   edi, buffer
 mov   ecx, 8
bitmaska:
 mov   al, 48
 shl   bl, 1       ; Shift a bit out into the carry
 adc   al, 0       ; Add that bit to the value 48
 stosb             ; Store '0' or '1' in the buffer
 dec   ecx
 jnz   bitmaska 

If the reverse order was intentional, then just replace shl bl, 1 by shr bl, 1.

发布评论

评论列表(0)

  1. 暂无评论