AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79125940
Accepted
Fatima sami
Fatima sami
Asked: 2024-10-25 21:36:53 +0800 CST2024-10-25 21:36:53 +0800 CST 2024-10-25 21:36:53 +0800 CST

Como faço para colocar o resultado na pilha em uma sub-rotina?

  • 772
org 0x0100      
jmp start  

; Declare variables
input1: db 0  
input2: db 7  
input3: db 9  
input4: db 1  
message1: db 'The value of AX, BX and CX is: '
length: dw 31

start:
    ; Push output variables with random values
    push 3       ; Random value 1
    push 5       ; Random value 2
    push 7       ; Random value 3

    call my_subroutine

    ; Retrieve output variables
    pop cx       ; Retrieve output into CX
    pop bx       ; Retrieve output into BX
    pop ax       ; Retrieve output into AX

    ;Display the output values
    call display
    
    ; Exit program
    mov ax, 0x4c00
    int 0x21

my_subroutine:
    ; Save registers
    push ax
    push bx
    push si
    push di
    push cx

    ; Local variables (initialized with random values)
    local1: dw 1
    local2: dw 2
    local3: dw 3
    local4: dw 4
    local5: dw 5

    ; Example operations (just random logic for demonstration)
    mov ax, [input1] ; Load first input
    add ax, [local1] ; Add local variable
    mov bx, [input2] ; Load second input
    sub bx, [local2] ; Subtract local variable

    ; Push results
    ;push ax          ; Push first output (AX)
    ;push bx          ; Push second output (BX)
    ;mov cx, word [input3]      
    ;push cx          ; Push third output (local variable)

    ; Restore registers
    pop cx           ; Pop last pushed value into CX
    pop bx           ; Restore BX
    pop ax           ; Restore AX
    pop di           ; Restore DI
    pop si           ; Restore SI
    ret              ; Return to the caller

cls:

  push es
  push ax
  push di

  mov ax, 0xB800
  mov es, ax
  mov di, 0

 allSpace:

 mov word [es:di], 0x0720
 add di, 2
 cmp di, 4000
 jne allSpace

 pop di
 pop ax
 pop es

 ret

convert_num_to_string:
    push bp
    mov bp, sp 
    push es
    pusha
    mov ax, 0xb800
    mov es, ax
    mov ax, [bp+4]
    mov bx, 10
    mov cx, 0

 nextdigit: 
    mov dx, 0
    div bx
    add dl, 0x30
    push dx
    inc cx
    cmp ax, 0
    jnz nextdigit


    nextpos: 
    pop dx
    mov dh, 0x07
    mov [es:di], dx
    add di, 2
    loop nextpos

    popa
    pop es
    pop bp
    ret 2

display_message:
  push bp
  mov bp, sp
  push es
  push ax
  push bx
  push cx

  mov ax, 0xb800
  mov es, ax

  mov si, [bp+6]
  mov cx, [bp+4]
  mov ah, 0x07

  printAllChar:
  
  mov al, [si]
  mov [es:di], ax
  add di, 2
  add si, 1
  loop printAllChar

  pop cx
  pop bx
  pop ax
  pop es
  pop bp
  ret 4

display:  
    call cls
    mov di, 0                  
    push message1                  
    push word [length]
    call display_message
    
    mov di, 62 
    push ax           
    call convert_num_to_string

    mov di, 66
    push bx           
    call convert_num_to_string

    mov di, 70
    push cx           
    call convert_num_to_string


    ret



Problema principal emmy_subroutine:

Na sub-rotina acima, quando eu envio meu resultado para a pilha, o controle não retorna ao início, mas sim um loop infinito é executado.

A propósito, aqui está a questão que estou tentando resolver:

Você precisa escrever uma sub-rotina em linguagem assembly que:

  1. Aceita 4 variáveis ​​de entrada (que serão os dígitos do seu número de registro, ou seja, 22F-3440, 3440 são as 4 entradas).
  2. Retorna 3 variáveis ​​de saída. Essas variáveis ​​de saída são empurradas (com valores aleatórios) antes das variáveis ​​de entrada no principal.
  3. Cria 5 variáveis ​​locais dentro da função. Inicializado com valores aleatórios de 1 a 10.
  4. Usa os registradores AX, BX, SI, DI e CX para executar operações, mas salva e restaura esses registradores antes e depois do uso para evitar sobrescrever seus valores originais.
  5. As saídas devem ser inseridas em AX, BX e CX após o retorno da sub-rotina.
  6. Exiba-os no console.
assembly
  • 1 1 respostas
  • 48 Views

1 respostas

  • Voted
  1. Best Answer
    Sep Roland
    2024-10-27T01:52:46+08:002024-10-27T01:52:46+08:00
    ; Local variables (initialized with random values)
    local1: dw 1
    local2: dw 2
    local3: dw 3
    local4: dw 4
    local5: dw 5
    

    Essas não são variáveis ​​locais! Elas são tão globais quanto as outras variáveis ​​que você declarou ( input , message , length ). Elas só parecem locais porque o nome delas diz isso e porque você as escreveu dentro da subrotina my_subroutine . Em muitos assemblers você poderia pelo menos tornar essas variáveis ​​'acessíveis somente localmente', adicionando um ponto aos seus nomes: .local1: dw 1. Mas isso ainda não é o ideal porque elas continuarão ocupando a memória delas enquanto seu programa estiver em execução.
    Além disso, por causa da colocação delas no caminho de execução do seu programa, a CPU executará esses bytes de dados com possíveis resultados desastrosos. No seu main você sabia que tinha que pular as declarações de dados com isso jmp start. Então, você poderia ter usado algo similar aqui.
    De qualquer forma, para sua tarefa a melhor solução é colocar as variáveis ​​locais na pilha. Veja o exemplo de código abaixo.

    ; Save registers
    push ax
    push bx
    push si
    push di
    push cx
    
    ...
    
    ; Restore registers
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    ret
    

    Você deve restaurar os registradores na ordem inversa de como você os empurrou antes. Exceto para CX, esse não é o caso aqui!

    1. Retorna 3 variáveis ​​de saída. Essas variáveis ​​de saída são empurradas (com valores aleatórios) antes das variáveis ​​de entrada no principal.

    Esta é uma frase importante e minha opinião sobre ela é que um total de 7 valores são colocados na pilha antes de chamar a subrotina. Como, diferentemente das variáveis ​​locais, nenhum limite foi colocado nos valores aleatórios, você pode economizar alguns bytes e simplesmente colocar qualquer valor (aleatório) que esteja nos registradores AX, BX e CX. Como alternativa, considere que a memória da pilha já está preenchida com esses valores "aleatórios" e, portanto, um mero sub sp, 6reservará o espaço para essas 3 saídas:

      ; Push output variables with random values
      push cx      ; (1)                 alternative:   sub sp, 6    ; (1)(2)(3)
      push bx      ; (2)
      push ax      ; (3)
      ; Push input variables with digits from roll number
      push 1       ; 4th digit
      push 9       ; 3rd digit
      push 7       ; 2nd digit
      push 0       ; 1st digit
      call my_subroutine
      pop  ax      ; (3)
      pop  bx      ; (2)
      pop  cx      ; (1)
    

    Layout da pilha quando estamos dentro da sub-rotina:

    1  2  3  4  5  CX DI SI BX AX BP RET 0  7  9  1  ?  ?  ?
    ^  ^                          ^      ^  ^        ^  ^  ^
    |  [bp-18]                    [bp]   |  [bp+6]   |  |  [bp+16]
    [bp-20]                              [bp+4]      |  [bp+14]
                                                     [bp+12]
    
    my_subroutine:
      push bp
      mov  bp, sp
      push ax      ; Save registers
      push bx
      push si
      push di
      push cx
      push 5       ; Local variables (initialized with random values)
      push 4
      push 3
      push 2
      push 1
    
      ; Example operations (just random logic for demonstration)
      mov  ax, [bp+4]    ; Load first input
      add  ax, [bp-20]   ; Add local variable
      mov  bx, [bp+6]    ; Load second input
      sub  bx, [bp-18]   ; Subtract local variable
      ...
    
    
      mov  [bp+12], ax   ; "Push" results
      mov  [bp+14], bx
      mov  [bp+16], cx
      add  sp, 10        ; Release local variables
      pop  cx            ; Restore registers
      pop  di
      pop  si
      pop  bx
      pop  ax
      pop  bp
      ret  8             ; Remove the 4 inputs
    

    display_message atualmente esquece de preservar SI e DI, mas preserva BX desnecessariamente. Também é um pouco estranho ver DI como uma entrada de registro para essa rotina junto com algumas entradas de pilha. Acho que 3 entradas de pilha OU 3 entradas de registro seriam melhores...

    • 3

relate perguntas

  • x86 - mudando de 32 bits para 64 bits via RETF

  • Opcode não reconhecido em instruções de montagem de ponto flutuante para Xiao ESP32-C3 (baseado em RISC-V)

  • Como usar o GNU Assembler (GAS) para criar um arquivo ELF escrito à mão a partir do arquivo .s correspondente

  • Não consigo ler o registro LY do gameboy

  • Obtenha o valor do parâmetro no Assembly

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve