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 / 79238530
Accepted
Joshua
Joshua
Asked: 2024-11-30 06:53:15 +0800 CST2024-11-30 06:53:15 +0800 CST 2024-11-30 06:53:15 +0800 CST

Superando "o operador de divisão só pode ser aplicado a valores escalares"

  • 772

O código de inicialização do aplicativo se parece com isto:

CPU 8086
_start:
    cld
    mov ax, ds
    dec ax
    mov es, ax
    mov ax, [es:3]
    cmp ax, word (_endbss + 768) / 16
    jae .mem
    ; Code would be here to emit an out of memory error

.mem:
    mov ax, 4C00h
    int 21h    

section .bss

_bss:
    big_array   resb    16384

_endbss:

O que ele deveria estar fazendo? Verificando se realmente temos RAM suficiente para executar o programa ou não.

O que ele está realmente fazendo? Não está montando.

A ideia geral é que precisamos de muita RAM, então configuramos Código + BSS + Pilha no segmento inicial e o slab acima dele (que excederá 64K por si só, então não faz sentido colocá-lo abaixo da pilha...). Estou convencido de que o assembler deve ser capaz de fazer isso, mas não consigo descobrir o que digitar para que funcione.

Como faço para obter a expressão que seria (_endbss + 768) / 16para montar a constante que definitivamente é? Eu realmente prefiro não ter que descobrir isso em tempo de execução.

assembly
  • 1 1 respostas
  • 19 Views

1 respostas

  • Voted
  1. Best Answer
    Peter Cordes
    2024-11-30T08:17:24+08:002024-11-30T08:17:24+08:00

    Infelizmente, o NASM -f binfunciona principalmente como um simples linker embutido no NASM. Ele não substitui as regras usuais de que qualquer matemática em endereços de símbolos deve ser representável com entradas de realocação, e não é conhecido no momento da montagem (apenas no momento do link).

    Mas você provavelmente ainda precisa de seções separadas para que resbelas possam ser incluídas .bsse não reunidas em bytes no arquivo de saída.


    Você pode somar os comprimentos das suas duas seções, partindo do princípio de que não há preenchimento para alinhamento entre as seções. (Você pode tornar isso uma realidade com section .bss align=1if esse não é o padrão, eu acho.) Então adicionamos um _endtextrótulo após o último byte de .text, e a instrução problemática se torna:

    cmp ax, word (_endbss - _bss  +  _endtext-_start + 768) / 16
    

    Listagem ( nasm -l /dev/stdout -f bin foo.asm) de um exemplo funcional:

         1                                  CPU 8086
         2                                  _start:
         3 00000000 FC                          cld
         4 00000001 8CD8                        mov ax, ds
         5 00000003 48                          dec ax
         6 00000004 8EC0                        mov es, ax
         7 00000006 26A10300                    mov ax, [es:3]
         8 0000000A 3D3104                      cmp ax, word (_endbss-_bss + _endtext-_start + 768) / 16
         9 0000000D 7300                        jae .mem
        10                                      ; Code would be here to emit an out of memory error
        11                                  
        12                                  .mem:
        13 0000000F B8004C                      mov ax, 4C00h
        14 00000012 CD21                        int 21h    
        15                                  
        16 00000014 B8[0040]                 mov ax, _endbss     ; for testing to see what value it puts here
        17 00000017 01000000                 dd 1                ; see what happens as the sign approaches 32...
        18                                  _endtext:
        19                                  section .bss
        20                                  
        21                                  _bss:
        22 00000000 <res 4000h>                 big_array   resb    16384
        23                                  
        24                                  _endbss:
        25                                  
    

    No arquivo de saída real foo, mov ax, _endbssmontado em b8 1c 40(não b8 00 40como a listagem mostra como um espaço reservado), então 1c 40(little-endian) = 0x401cé a parte deslocada do endereço completo e é o que você queria _endbssavaliar.

    A comparação imediata é little-endian, 31 04que é 0x0431.

    Insira esse _endbssvalor na sua expressão para verificar os resultados:
    (0x401c + 768) / 16arredonda para baixo para 1073, que é 0x431o valor que minha expressão obteve para cmp.

    Não testei exaustivamente com extras times x db 1em tamanhos .ext ou que não sejam potências de 2 .bsspara garantir que não haja desvio de um em um corte entre o próximo tamanho ou corte para o próximo nível de preenchimento de alinhamento, se houver.

    • 2

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